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
/*********** tcpserver.c **********/
by : prasad
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>/*close*/
#define SUCCESS 0
#define ERROR 1
#define END_LINE 0x0
#define SERVER_PORT 1500
#define MAX_MSG 100
/* function readline */
int read_line();
int main (int argc, char *argv[])
{
int sd, newSd, cliLen;
struct sockaddr_in cliAddr, servAddr;
char line[MAX_MSG];
/* create socket */
sd = socket(AF_INET, SOCK_STREAM, 0);
if(sd<0) {
perror("cannot open socket ");
return ERROR;
}
/* bind server port */
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
servAddr.sin_port = htons(SERVER_PORT);
if(bind(sd, (struct sockaddr *) &servAddr,
sizeof(servAddr))<0) {
perror("cannot bind port ");
return ERROR;
}
listen(sd,5);
while(1) {
printf("%s: waiting for data on port TCP %un"
,argv[0],SERVER_PORT);
cliLen = sizeof(cliAddr);
newSd = accept(sd, (struct sockaddr *)
&cliAddr, &cliLen);
if(newSd<0) {
perror("cannot accept connection ");
return ERROR;
}
/* init line */
memset(line,0x0,MAX_MSG);
/* receive segments */
while(read_line(newSd,line)!=ERROR) {
printf("%s: received from %s:TCP%d :
%sn", 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 clientn");
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 =<returnline*/
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;
}
} /* while */
}
/******* tcpclient.c *******/
/* tcpClient.c */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h> /*close*/
#define SERVER_PORT 1500
#define MAX_MSG 100
int main (int argc, char *argv[]) {
int sd, rc, i;
struct sockaddr_in localAddr, servAddr;
struct hostent *h;
if(argc < 3) {
printf("usage: %s <server> <data1>
<data2> ... <dataN>n",argv[0]);
exit(1);
}
h = gethostbyname(argv[1]);
if(h==NULL) {
printf("%s: unknown host '%s'n"
,argv[0],argv[1]);
exit(1);
}
servAddr.sin_family = h-<h_addrtype;
memcpy((char *) &servAddr.sin_addr.s_addr,
h-<h_addr_list[0],h-<h_length);
servAddr.sin_port = htons(SERVER_PORT);
/* create socket */
sd = socket(AF_INET, SOCK_STREAM, 0);
if(sd<0) {
perror("cannot open socket ");
exit(1);
}
/* bind any port number */
localAddr.sin_family = AF_INET;
localAddr.sin_addr.s_addr =
htonl(INADDR_ANY);
localAddr.sin_port = htons(0);
rc = bind(sd, (struct sockaddr *) &
localAddr, sizeof(localAddr));
if(rc<0) {
printf("%s: cannot bind port TCP %un",
argv[0],SERVER_PORT);
perror("error ");
exit(1);
}
/* connect to server */
rc = connect(sd, (struct sockaddr *)
&servAddr, sizeof(servAddr));
if(rc<0) {
perror("cannot connect ");
exit(1);
}
for(i=2;i<argc;i++) {
rc = send(sd, argv[i], strlen(argv[i])
+ 1, 0);
if(rc<0) {
perror("cannot send data ");
close(sd);
exit(1);
}
printf("%s: data%u sent (%s)n",
argv[0],i-1,argv[i]);
}
return 0;
}
* 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
/*********** tcpserver.c **********/
by : prasad
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>/*close*/
#define SUCCESS 0
#define ERROR 1
#define END_LINE 0x0
#define SERVER_PORT 1500
#define MAX_MSG 100
/* function readline */
int read_line();
int main (int argc, char *argv[])
{
int sd, newSd, cliLen;
struct sockaddr_in cliAddr, servAddr;
char line[MAX_MSG];
/* create socket */
sd = socket(AF_INET, SOCK_STREAM, 0);
if(sd<0) {
perror("cannot open socket ");
return ERROR;
}
/* bind server port */
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
servAddr.sin_port = htons(SERVER_PORT);
if(bind(sd, (struct sockaddr *) &servAddr,
sizeof(servAddr))<0) {
perror("cannot bind port ");
return ERROR;
}
listen(sd,5);
while(1) {
printf("%s: waiting for data on port TCP %un"
,argv[0],SERVER_PORT);
cliLen = sizeof(cliAddr);
newSd = accept(sd, (struct sockaddr *)
&cliAddr, &cliLen);
if(newSd<0) {
perror("cannot accept connection ");
return ERROR;
}
/* init line */
memset(line,0x0,MAX_MSG);
/* receive segments */
while(read_line(newSd,line)!=ERROR) {
printf("%s: received from %s:TCP%d :
%sn", 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 clientn");
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 =<returnline*/
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;
}
} /* while */
}
/******* tcpclient.c *******/
/* tcpClient.c */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h> /*close*/
#define SERVER_PORT 1500
#define MAX_MSG 100
int main (int argc, char *argv[]) {
int sd, rc, i;
struct sockaddr_in localAddr, servAddr;
struct hostent *h;
if(argc < 3) {
printf("usage: %s <server> <data1>
<data2> ... <dataN>n",argv[0]);
exit(1);
}
h = gethostbyname(argv[1]);
if(h==NULL) {
printf("%s: unknown host '%s'n"
,argv[0],argv[1]);
exit(1);
}
servAddr.sin_family = h-<h_addrtype;
memcpy((char *) &servAddr.sin_addr.s_addr,
h-<h_addr_list[0],h-<h_length);
servAddr.sin_port = htons(SERVER_PORT);
/* create socket */
sd = socket(AF_INET, SOCK_STREAM, 0);
if(sd<0) {
perror("cannot open socket ");
exit(1);
}
/* bind any port number */
localAddr.sin_family = AF_INET;
localAddr.sin_addr.s_addr =
htonl(INADDR_ANY);
localAddr.sin_port = htons(0);
rc = bind(sd, (struct sockaddr *) &
localAddr, sizeof(localAddr));
if(rc<0) {
printf("%s: cannot bind port TCP %un",
argv[0],SERVER_PORT);
perror("error ");
exit(1);
}
/* connect to server */
rc = connect(sd, (struct sockaddr *)
&servAddr, sizeof(servAddr));
if(rc<0) {
perror("cannot connect ");
exit(1);
}
for(i=2;i<argc;i++) {
rc = send(sd, argv[i], strlen(argv[i])
+ 1, 0);
if(rc<0) {
perror("cannot send data ");
close(sd);
exit(1);
}
printf("%s: data%u sent (%s)n",
argv[0],i-1,argv[i]);
}
return 0;
}