C Tutorial: Socket Programming in C using TCP with Code
by: jawahar, 10/4/2005 1:13:31 AM, Views: 6901
To compile :
* linux : gcc -Wall -o foo foo.c * solaris : gcc -Wall -o foo foo.c -lsocket -lnsl
1. TCP
* TCP server : simple TCP server that prints received messages. source : tcpServer.c usage : ./tcpServer * TCP client : simple TCP client that sends data to server. source : tcpClient.c usage : ./tcpClient server data1 ... dataN
printf("%s: received from %s:TCP%d : %s\n", argv[0], inet_ntoa(cliAddr.sin_addr), ntohs(cliAddr.sin_port), line); /* init line */ memset(line,0x0,MAX_MSG);
} /* while(read_line) */
} /* while (1) */
}
/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING */ /* this function is experimental.. I don't know yet if it works */ /* correctly or not. Use Steven's readline() function to have */ /* something robust. */ /* WARNING WARNING WARNING WARNING WARNING WARNING WARNING */
/* rcv_line is my function readline(). Data is read from the socket when */ /* needed, but not byte after bytes. All the received data is read. */ /* This means only one call to recv(), instead of one call for */ /* each received byte. */ /* You can set END_CHAR to whatever means endofline for you. (0x0A is \n)*/ /* read_lin returns the number of bytes returned in line_to_return */ int read_line(int newSd, char *line_to_return) {
static int rcv_ptr=0; static char rcv_msg[MAX_MSG]; static int n; int offset;
offset=0;
while(1) { if(rcv_ptr==0) { /* read data from socket */ memset(rcv_msg,0x0,MAX_MSG); /* init buffer */ n = recv(newSd, rcv_msg, MAX_MSG, 0); /* wait for data */ if (n<0) { perror(" cannot receive data "); return ERROR; } else if (n==0) { printf(" connection closed by client\n"); close(newSd); return ERROR; } }
/* if new data read on socket */ /* OR */ /* if another line is still in buffer */
/* copy line into 'line_to_return' */ while(*(rcv_msg+rcv_ptr)!=END_LINE && rcv_ptr<n) { memcpy(line_to_return+offset,rcv_msg+rcv_ptr,1); offset++; rcv_ptr++; }
/* end of line + end of buffer => return line */ if(rcv_ptr==n-1) { /* set last byte to END_LINE */ *(line_to_return+offset)=END_LINE; rcv_ptr=0; return ++offset; }
/* end of line but still some data in buffer => return line */ if(rcv_ptr <n-1) { /* set last byte to END_LINE */ *(line_to_return+offset)=END_LINE; rcv_ptr++; return ++offset; }
/* end of buffer but line is not ended => */ /* wait for more data to arrive on socket */ if(rcv_ptr == n) { rcv_ptr = 0; }