/*
@filename : client.c
@brief: Client Program
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#define MAX_LINE 256
void *SendReceive(void* sockid);
int main(int argc,char *argv[])
{
struct sockaddr_in serv_addr ;
int sockid, tcp_port ;
pthread_t th;
if(argc < 3 )
{
printf("usage: %s <server-address> <port> \n",argv[0]);
return -1;
}
tcp_port = atoi(argv[2]) ;
sockid = socket(AF_INET,SOCK_STREAM,0) ;
if(sockid == -1 )
{
printf("Failed to get socket\n");
return -2;
}
serv_addr.sin_family = AF_INET ;
serv_addr.sin_addr.s_addr = inet_addr(argv[1]) ;
serv_addr.sin_port = htons(tcp_port) ;
if(connect(sockid,(struct sockaddr*)&serv_addr,sizeof(serv_addr)) != 0)
{
printf("Failed to Connect Server %s\n",argv[2]);
return -3 ;
}
if (pthread_create (&th, NULL, SendReceive, (void*)sockid) != 0)
{
close(sockid) ;
return -4 ;
}
pthread_join(th,NULL);
close(sockid);
return 0 ;
}
void *SendReceive(void* sockfd)
{
char buf[MAX_LINE],sendbuf[MAX_LINE];
int length,ret,sockid ;
sockid =(int)sockfd;
while(1)
{
memset(buf,0,sizeof(buf));
if(fgets(buf,MAX_LINE,stdin) == NULL )
{
printf ("received EOF from stdin\n");
break;
}
length = strlen(buf);
if( (ret = send(sockid, &buf, length, 0)) <= 0 )
{
printf("Client coultn't send message to server\n");
break;
}
ret = recv(sockid,&buf,MAX_LINE,0);
if ( ret == 0 )
{
break;
}
else if ( ret < 0 )
{
printf("Error Occurs Err[#%d,%s]\n", errno, strerror(errno) );
break;
}
printf("%s",buf);
}
return NULL;
}
/*
@filename : server.c
@brief: Concurrent Server Program
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#define MAX_LINE 256
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
int conn_count=0;
void *HandlingClient(void *);
int main(int argc,char *argv[])
{
struct sockaddr_in serv_addr, client_addr;
int sockid, newsockid, tcp_port, len;
pthread_t tid;
if(argc < 2 )
{
printf("usage: %s <port>\n", argv[0]);
return -1;
}
tcp_port = atoi(argv[1]);
sockid = socket(AF_INET,SOCK_STREAM,0);
if(sockid < 0 )
{
printf("Failed to get socket\n");
return -1;
}
len=1;
setsockopt (sockid, SOL_SOCKET, SO_REUSEADDR, &len, sizeof(int));
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(tcp_port);
if((bind(sockid,(struct sockaddr*)&serv_addr,sizeof(serv_addr))) != 0)
{
printf("Failed to bind\n");
return -2;
}
pthread_mutex_init(&mutex, NULL);
listen(sockid,128);
while (1)
{
printf("active connections #%d\n", conn_count);
len = sizeof(client_addr);
if((newsockid = accept(sockid,(struct sockaddr*)&client_addr,&len)) == -1)
{
printf("Failed to accept the client request\n");
continue;
}
if(pthread_create(&tid, NULL, HandlingClient, (void*)newsockid) != 0 )
{
printf("Failed to create thread\n");
close (newsockid);
sleep (1);
continue;
}
pthread_mutex_lock(&mutex);
conn_count ++;
pthread_mutex_unlock(&mutex);
}
pthread_mutex_destroy(&mutex);
return 0;
}
void *HandlingClient(void *id)
{
char buf[MAX_LINE];
int ret, sockid;
sockid = (int)id;
while(1)
{
ret = recv(sockid,&buf,MAX_LINE,0);
if ( ret == 0 )
{
break;
}
else if ( ret < 0 )
{
printf("Error Occurs Err[#%d,%s]\n", errno, strerror(errno) );
break;
}
if(!strncasecmp(buf,"bye",3))
{
pthread_mutex_lock(&mutex);
conn_count--;
pthread_mutex_unlock(&mutex);
break;
}
/* send back to client*/
if( (ret = send(sockid, &buf, ret, 0)) <= 0 )
{
printf("Client coultn't send message to server\n");
break;
}
}
close(sockid);
return NULL;
}
Makefile:
MESSAGE="Echo Program Built Successfully"
MESSAGE1 = " ------------------------- "
CC = gcc
CFLAGS = -g -I./include
all: server client
@echo $(MESSAGE1)
@echo $(MESSAGE)
@echo $(MESSAGE1)
server: server.o
${CC} -o $@ server.o -lpthread
client: client.o
${CC} -o $@ client.o -lpthread
clean:
-@rm *.o
distclean: clean
-@rm server client
@filename : client.c
@brief: Client Program
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#define MAX_LINE 256
void *SendReceive(void* sockid);
int main(int argc,char *argv[])
{
struct sockaddr_in serv_addr ;
int sockid, tcp_port ;
pthread_t th;
if(argc < 3 )
{
printf("usage: %s <server-address> <port> \n",argv[0]);
return -1;
}
tcp_port = atoi(argv[2]) ;
sockid = socket(AF_INET,SOCK_STREAM,0) ;
if(sockid == -1 )
{
printf("Failed to get socket\n");
return -2;
}
serv_addr.sin_family = AF_INET ;
serv_addr.sin_addr.s_addr = inet_addr(argv[1]) ;
serv_addr.sin_port = htons(tcp_port) ;
if(connect(sockid,(struct sockaddr*)&serv_addr,sizeof(serv_addr)) != 0)
{
printf("Failed to Connect Server %s\n",argv[2]);
return -3 ;
}
if (pthread_create (&th, NULL, SendReceive, (void*)sockid) != 0)
{
close(sockid) ;
return -4 ;
}
pthread_join(th,NULL);
close(sockid);
return 0 ;
}
void *SendReceive(void* sockfd)
{
char buf[MAX_LINE],sendbuf[MAX_LINE];
int length,ret,sockid ;
sockid =(int)sockfd;
while(1)
{
memset(buf,0,sizeof(buf));
if(fgets(buf,MAX_LINE,stdin) == NULL )
{
printf ("received EOF from stdin\n");
break;
}
length = strlen(buf);
if( (ret = send(sockid, &buf, length, 0)) <= 0 )
{
printf("Client coultn't send message to server\n");
break;
}
ret = recv(sockid,&buf,MAX_LINE,0);
if ( ret == 0 )
{
break;
}
else if ( ret < 0 )
{
printf("Error Occurs Err[#%d,%s]\n", errno, strerror(errno) );
break;
}
printf("%s",buf);
}
return NULL;
}
/*
@filename : server.c
@brief: Concurrent Server Program
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#define MAX_LINE 256
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
int conn_count=0;
void *HandlingClient(void *);
int main(int argc,char *argv[])
{
struct sockaddr_in serv_addr, client_addr;
int sockid, newsockid, tcp_port, len;
pthread_t tid;
if(argc < 2 )
{
printf("usage: %s <port>\n", argv[0]);
return -1;
}
tcp_port = atoi(argv[1]);
sockid = socket(AF_INET,SOCK_STREAM,0);
if(sockid < 0 )
{
printf("Failed to get socket\n");
return -1;
}
len=1;
setsockopt (sockid, SOL_SOCKET, SO_REUSEADDR, &len, sizeof(int));
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(tcp_port);
if((bind(sockid,(struct sockaddr*)&serv_addr,sizeof(serv_addr))) != 0)
{
printf("Failed to bind\n");
return -2;
}
pthread_mutex_init(&mutex, NULL);
listen(sockid,128);
while (1)
{
printf("active connections #%d\n", conn_count);
len = sizeof(client_addr);
if((newsockid = accept(sockid,(struct sockaddr*)&client_addr,&len)) == -1)
{
printf("Failed to accept the client request\n");
continue;
}
if(pthread_create(&tid, NULL, HandlingClient, (void*)newsockid) != 0 )
{
printf("Failed to create thread\n");
close (newsockid);
sleep (1);
continue;
}
pthread_mutex_lock(&mutex);
conn_count ++;
pthread_mutex_unlock(&mutex);
}
pthread_mutex_destroy(&mutex);
return 0;
}
void *HandlingClient(void *id)
{
char buf[MAX_LINE];
int ret, sockid;
sockid = (int)id;
while(1)
{
ret = recv(sockid,&buf,MAX_LINE,0);
if ( ret == 0 )
{
break;
}
else if ( ret < 0 )
{
printf("Error Occurs Err[#%d,%s]\n", errno, strerror(errno) );
break;
}
if(!strncasecmp(buf,"bye",3))
{
pthread_mutex_lock(&mutex);
conn_count--;
pthread_mutex_unlock(&mutex);
break;
}
/* send back to client*/
if( (ret = send(sockid, &buf, ret, 0)) <= 0 )
{
printf("Client coultn't send message to server\n");
break;
}
}
close(sockid);
return NULL;
}
Makefile:
MESSAGE="Echo Program Built Successfully"
MESSAGE1 = " ------------------------- "
CC = gcc
CFLAGS = -g -I./include
all: server client
@echo $(MESSAGE1)
@echo $(MESSAGE)
@echo $(MESSAGE1)
server: server.o
${CC} -o $@ server.o -lpthread
client: client.o
${CC} -o $@ client.o -lpthread
clean:
-@rm *.o
distclean: clean
-@rm server client
output example:
ReplyDelete#./server 1444
#./client 10.20.50.2 1444
hello
hello
bye
#
say "bye" to end up the session
instead of recv and send system call, we can use read and write , the difference is the fourth argument of recv/send where we can set the flags for socket recv and send operation , in case of read and write the same may not be possible !!
ReplyDeleteWhy do we use bind ? Why bind used for server program , why not in client program ?
ReplyDelete- Basically bind means that binding port on the given ip address i.e interface
- we can either bind on all interface available on the server , INADDR_ANY macro preferred for this
- Also can restrict bind to single interface, so other interfaces can be used for other application in tern will react as multiple machines
- Client no need to bind on port, since its a sender also might be some other server could have used the same port on client host
With UDP, client have to bind() the socket in the client because UDP is connectionless, so there is no other way for the stack to know which program to deliver datagrams to for a particular port.
DeleteIf you could recvfrom() without bind(), you'd essentially be asking the stack to give your program all UDP datagrams sent to that computer. Since the stack delivers datagrams to only one program, this would break DNS, Windows' Network Neighborhood, network time sync