![]() |
| | #1 | |||
| Registered User Join Date: Nov 2009
Posts: 36
| TCP/IP Socket Programming Exercise So to run it for example it type the following format: Quote:
Quote:
My problem is, however when I try this the program just shows a flashing block on the line below as if it's waiting / trying to connect. So, my next logical thought was to change the ip to the loopback address but this returns : Quote:
Code: #include <stdio.h> /* for printf() and fprintf() */
#include <sys/socket.h> /* for socket(), connect(), send(), and recv() */
#include <arpa/inet.h> /* for sockaddr_in and inet_addr() */
#include <stdlib.h> /* for atoi() and exit() */
#include <string.h> /* for memset() */
#include <unistd.h> /* for close() */
#define RCVBUFSIZE 32 /* Size of receive buffer */
void DieWithError(char *errorMessage); /* Error handling function */
int main(int argc, char *argv[])
{
int sock; /* Socket descriptor */
struct sockaddr_in echoServAddr; /* Echo server address */
unsigned short echoServPort; /* Echo server port */
char *servIP; /* Server IP address (dotted quad) */
char *echoString; /* String to send to echo server */
char echoBuffer[RCVBUFSIZE]; /* Buffer for echo string */
unsigned int echoStringLen; /* Length of string to echo */
int bytesRcvd, totalBytesRcvd; /* Bytes read in single recv()
and total bytes read */
if ((argc < 3) || (argc > 4)) /* Test for correct number of arguments */
{
fprintf(stderr, "Usage: %s <Server IP> <Echo Word> [<Echo Port>]\n",
argv[0]);
exit(1);
}
servIP = argv[1]; /* First arg: server IP address (dotted quad) */
echoString = argv[2]; /* Second arg: string to echo */
if (argc == 4)
echoServPort = atoi(argv[3]); /* Use given port, if any */
else
echoServPort = 7; /* 7 is the well-known port for the echo service */
/* Create a reliable, stream socket using TCP */
if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
DieWithError("socket() failed");
/* Construct the server address structure */
memset(&echoServAddr, 0, sizeof(echoServAddr)); /* Zero out structure */
echoServAddr.sin_family = AF_INET; /* Internet address family */
echoServAddr.sin_addr.s_addr = inet_addr(servIP); /* Server IP address */
echoServAddr.sin_port = htons(echoServPort); /* Server port */
/* Establish the connection to the echo server */
if (connect(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)
DieWithError("connect() failed");
echoStringLen = strlen(echoString); /* Determine input length */
/* Send the string to the server */
if (send(sock, echoString, echoStringLen, 0) != echoStringLen)
DieWithError("send() sent a different number of bytes than expected");
/* Receive the same string back from the server */
totalBytesRcvd = 0;
printf("Received: "); /* Setup to print the echoed string */
while (totalBytesRcvd < echoStringLen)
{
/* Receive up to the buffer size (minus 1 to leave space for
a null terminator) bytes from the sender */
if ((bytesRcvd = recv(sock, echoBuffer, RCVBUFSIZE - 1, 0)) <= 0)
DieWithError("recv() failed or connection closed prematurely");
totalBytesRcvd += bytesRcvd; /* Keep tally of total bytes */
echoBuffer[bytesRcvd] = '\0'; /* Terminate the string! */
printf("%s", echoBuffer); /* Print the echo buffer */
}
printf("\n"); /* Print a final linefeed */
close(sock);
exit(0);
}
| |||
| Martin_T is offline | |
| | #2 |
| Registered User Join Date: Oct 2006 Location: Canada
Posts: 848
| Well the logical place to start is: what is the error? Use a "select" statement to find out what caused connect to fail, by checking "errno" against the various error constants (or use some function that does this for you). A list of some is here: connect - Linux Command - Unix Command. So do something like Code: if (connect(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)
{
select (errno)
{
case EBADF: printf("EBADF\n");
case // ...
}
|
| nadroj is offline | |
| | #3 |
| subminimalist Join Date: Jul 2008 Location: NYC
Posts: 3,944
| Port 7 is a standard port used for an echo service, but you will have to find a server that actually has one running -- your own computer almost certainly does not*. I think these are generally disabled now because they can be used in "smurf" or "fraggle" attacks, whereby someone sends an echo request using a spoofed ip to as many echo servers as they can. The servers then reply to the spoofed ip (which would be the victim of the attack); that ip is effectively flooded with incoming messages from all over the place. *ie, you cannot connect because there is no one to accept() the call.
__________________ Accuracy and integrity mean nothing if you don't make it past the censors...PYTHAGORAS |
| MK27 is offline | |
| | #4 |
| Registered User Join Date: Nov 2009
Posts: 36
| Thanks for reply, I only get a connection error if I put the loopback address in.If I enter the suggested command it justs waits with the cursor flashing. The code is a direct download so I assume it is correct. I just wondered if there was something more basic I had done wrong as I am new to C and new to networking. Thanks again |
| Martin_T is offline | |
| | #5 | |
| Registered User Join Date: Nov 2009
Posts: 36
| Quote:
Hmm.... it's a recent print book. Is there a way to enable port 7 temporarily or is it not advised even short-term? Or is there a different port I could try that would be more likely to work? and do you have any idea what the suggested ip address 169.1.1.1 would be? Thanks again | |
| Martin_T is offline | |
| | #6 | ||
| Registered User Join Date: Oct 2006 Location: Canada
Posts: 848
| Quote:
Quote:
| ||
| nadroj is offline | |
| | #7 | |
| subminimalist Join Date: Jul 2008 Location: NYC
Posts: 3,944
| Quote:
But nothing in the network card or the operating system answers ports automatically. You have to provide some software. The code you have above is a simple client. What you need is a simple server as well -- this is the first thing people do learning networking, they write little clients and servers that work together. Gimme a few minutes and I'll post you something that should work like an echo server on a linux box... ps. I have no idea what 169.1.1.1 would be. In what sense is it "suggested"? I'm not even sure if that is a valid "A level" address, 169 could be a LAN address.
__________________ Accuracy and integrity mean nothing if you don't make it past the censors...PYTHAGORAS | |
| MK27 is offline | |
| | #8 |
| subminimalist Join Date: Jul 2008 Location: NYC
Posts: 3,944
| Okay! I'm getting better at this ![]() Code: #include <stdio.h> /* for printf() and fprintf() */
#include <sys/socket.h> /* for socket(), connect(), send(), and recv() */
#include <arpa/inet.h> /* for sockaddr_in and inet_addr() */
#include <stdlib.h> /* for atoi() and exit() */
#include <string.h> /* for memset() */
#include <unistd.h> /* for close() */
#define PORT 7
int server_sock (int port) {
struct sockaddr_in Me;
int sock;
if ((sock=socket(PF_INET, SOCK_STREAM, 0))<3) perror("socket");
Me.sin_family=AF_INET;
Me.sin_port=htons(port);
Me.sin_addr.s_addr=INADDR_ANY;
memset(&(Me.sin_zero), '\0', 8);
if (bind(sock,(struct sockaddr*)&Me,sizeof(struct sockaddr))==-1) perror("bind");
if (listen(sock,2)!=0) perror("listen");
return sock;
}
int main() {
char buffer[256];
struct sockaddr_in info;
socklen_t size=sizeof(struct sockaddr_in);
int self = server_sock(PORT),
other = accept(self,(struct sockaddr*)&info,&size);
recv(other,buffer,255,0);
send(other,buffer,strlen(buffer),0);
close(other);
close(self);
return 0;
}
In the second terminal you will see: Received: helloWorld! and then both programs will end. I just tried this here (I had to add the "DieWithError" function to your code) and it works fine. Notice the server is automatically on the loopback interface, 127.0.0.1. I believe that most linux systems have this enabled by default -- if you have a problem, that is probably it, then we just have to figure out how to start that on your box
__________________ Accuracy and integrity mean nothing if you don't make it past the censors...PYTHAGORAS |
| MK27 is offline | |
| | #9 | |
| Registered User Join Date: Nov 2009
Posts: 36
| Quote:
The chapter is on the TCP client only and at the end gives an example where I compile this code and get a response. However, it looks like maybe the ip address should have an echo server running on it. Seems strange as the next chapter is on the tcp server at the end of which I run both client and server together. Sorry to be asking stupid questions, I just thought this code would take on both functions of sending a receiving. | |
| Martin_T is offline | |
| | #10 | |
| Registered User Join Date: Nov 2009
Posts: 36
| Quote:
Worked great thanks. Although it added a "K" to the end of the recieved data. And it wouldnt run a second time. It says "bind : Address already in use" But it worked fine to allow me to see the concept. Now all I've got to do is work through this book. Thankyou once again. I appreciate your time and your help. | |
| Martin_T is offline | |
![]() |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Problem with socket descriptors | McKracken | C Programming | 1 | 07-22-2009 08:51 AM |
| Line of data input method | larry_2k4 | C Programming | 2 | 04-28-2009 11:34 PM |
| Request for comments | Prelude | A Brief History of Cprogramming.com | 15 | 01-02-2004 10:33 AM |
| TCP/IP and Socket programming | CompiledMonkey | C Programming | 2 | 02-21-2003 03:47 PM |
| TCP/IP Socket | Nor | Linux Programming | 4 | 04-22-2002 11:21 AM |