Professional Documents
Culture Documents
AV341
INDEX
No. Date Topic Remarks
OBJECTIVE:
To Create a simple Echo Server and Client using Linux TCP Socket APIs and to modify the Echo Server with a String Reverse Service
clilen = sizeof(cli_addr); newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); if (newsockfd < 0) perror("server: accept error"); if ( (childpid = fork()) < 0) perror("server: fork error"); else if (childpid == 0) { /* child process */ close(sockfd); /* close original socket */ str_echo(newsockfd); /* process the request */ exit(0); } close(newsockfd); /* parent process */ } } /* * Read a stream socket one line at a time, and write each line back * to the sender. * * Return when the connection is terminated. */ str_echo(sockfd) int sockfd; { int n; char line[MAXLINE]; char c; int i; for ( ; ; ) { n = recv(sockfd, line, MAXLINE, 0); /*String is received from the client*/ if (n == 0) return; /* connection terminated */ else if (n < 0) perror("str_echo: readline error"); /*This loop will do the string reversal*/ else if (send(sockfd, line, n,0) != n) /*Reversed String is sent back to client*/ perror("str_echo: writen error"); } }
char *pname; /* * Example of client using TCP protocol. */ main(argc, argv) int argc; char *argv[]; { int sockfd; struct sockaddr_in serv_addr; // char SERVER_IP_ADDR[25]; /* host addr for server:pname = argv[0]; /* * Fill in the structure "serv_addr" with the address of the * server that we want to connect with. */ // strcpy(SERVER_IP_ADDR,"localhost"); bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = inet_addr(SERV_HOST_ADDR); serv_addr.sin_port = htons(SERV_TCP_PORT); /* * Open a TCP socket (an Internet stream socket). */ if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) perror("client: can't open stream socket"); /* * Connect to the server. */ if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) perror("client: can't connect to server"); str_cli(stdin, sockfd); /* do it all */ close(sockfd); exit(0); } /* * Read the contents of the FILE *fp, write each line to the * stream socket (to the server process), then read a line back from * the socket and write it to the standard output. * * Return to caller when an EOF is encountered on the input file. */ str_cli(fp, sockfd) register FILE *fp; register int sockfd; { int n; char sendline[MAXLINE], recvline[MAXLINE + 1]; printf("Enter the string to be sent to the server\n"); while (fgets(sendline, MAXLINE, fp) != NULL) { n = strlen(sendline); printf("Sending %d bytes to server at %s \n",n,SERV_HOST_ADDR); if (send(sockfd, sendline, n,0) != n) perror("str_cli: writen error on socket"); /* * Now read a line from the socket and write it to * our standard output. */
n = recv(sockfd, recvline, MAXLINE,0); if (n < 0) perror("str_cli: readline error"); recvline[n] = 0; /* null terminate */ printf("Received From Server: "); fputs(recvline, stdout); } if (ferror(fp)) perror("str_cli: error reading file"); }
perror("server: accept error"); if ( (childpid = fork()) < 0) perror("server: fork error"); else if (childpid == 0) { /* child process */ close(sockfd); /* close original socket */ str_echo(newsockfd); /* process the request */ exit(0); } close(newsockfd); /* parent process */ } } /* * Read a stream socket one line at a time, and write each line back * to the sender. * * Return when the connection is terminated. */ str_echo(sockfd) int sockfd; { int n; char line[MAXLINE]; char c; int i; for ( ; ; ) { n = recv(sockfd, line, MAXLINE, 0); /*String is received from the client*/ if (n == 0) return; /* connection terminated */ else if (n < 0) perror("str_echo: readline error"); for (i=0;i<(n/2);i++) { c= line[i]; line[i]=line[n-i-1]; line[n-i-1]=c; } /*This loop will do the string reversal*/ if (send(sockfd, line, n,0) != n) /*Reversed String is sent back to client*/ perror("str_echo: writen error"); } }
CLIENT:
Gedit client.c //opens up the file with name client.c Copy and paste the client code in above file and edit the host address with ip address of server. gcc client.c //gcc compiler compliles the code in file Ping 172.20.111.67 //checks the connection status with the server 127.0.0.1 //is used when both server and client are on the same system. ./a.out // runs the complied code
OUTPUTS: SERVER:
CLIENT:
This is a handshake process. Connection is setup between client and server. So whatever message sent from client is processed in server and sent back to client.
Address already in use: if the terminal is already open for the same program with same port number, then we get this error. It can get overcome by changing the port number. CLIENT:
The string sent by client is processed in the server and the reversal of the string is sent back to the client.
INFERENCE: For user to interact with network ,API(Application program interface) is needed sometimes called as socket APIs.We need to have sequence of tasks to establish a connection between client and server.Here connection-oriented data transfer is focused (TCP).In TCP streams of data is sent (byte stream).Echo server means the data client sends to server is reflected back to client on terminal (with or without reversal).We use following functions to open and set up TCP connection :
SOCKET APIS: Int socket (int domain, int type, int protocol) included both in client & server domain specifies a communication family selects protocol family type is type of communication,end to end semantics eg: SOCK-STREAM, SOCK-DGRAM, SOCK-RAM, SOCK-RDM. protocol defines protocol to be used in communication
Int bind (int socket-id, struct sock addr, int addr-less) Unique to server bind ( ) socket call binds or attaches new socket with local address addr. socket id is socket identifier/file descriptor struct sock addr is a structure contain address
int listen( int socket-fd,int backing) unique to server side sockets listen( ) API specifies in coming connection & a queue limit in incoming connection on a newly created socket int socket-fd specifies socket int backing define max length of queue of pending connection.
int accept ( int socket-fd, structure sockaddr,sock len-taddrlen) used with connection based socket it extracts a first connection and creates a new socket it returns file descriptive of new socket new socket is not in listening state int struct-fd is original socket struct sockaddr is a pointer to sock addr structure this structure is filled with address of peer socket that is accepted to communication sessions
int connect(int socket-fd, construct sock addr, serv addrs) requests connection using referred socket by file descriptor to address specified by serv-addr send( ), send to ( ) , send msg => transmit a message to another socket
recv( ) , recvfrom( ), recv msg( ) =>it can be blocking but is normally used as a connected socket with known remake addr int shutdown (int socket-fd,int how) => how determines communication after shutdown
CONCLUSION: Initially connection between server and client was established using the ip
address of the server. Whatever messages send from the client to server has been received back by the client again. Program for string reversal in C code is included in the server code. When server receives a string from the client, the string gets reversed as per the C code and the reversed string is sent back to client.