simple client server in c - c

i am not able to understand why the code is not working. sendall and revcall are taken from beej guide. Their is no output when i send the data from server to client. Can someone please explain the error in code. It is mostly from beej guide.One of the problems in broken pipe i.e reading when port is closed but when the port is closed i am not able to understand.
server code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define MAX_SIZE 50
void error(const char *msg)
{
perror(msg);
exit(1);
}
/* sends all data - thanks to Beej's Guide to Network Programming */
int sendall(int s, char *buf, int *len)
{
int total=0;
int bytesleft=*len;
int n=0;
/* send all the data */
while(total<*len)
{
/* send some data */
n=send(s,buf+total,bytesleft,0);
/* break on error */
if(n==-1)
break;
/* apply bytes we sent */
total+=n;
bytesleft-=n;
}
/* return number of bytes actually send here */
*len=total;
/* return -1 on failure, 0 on success */
return n==-1?-1:0;
}
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno;
socklen_t clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;
if (argc < 2)
{
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
printf("sockfd : %d",sockfd);
if (sockfd < 0)
error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
error("ERROR on binding");
listen(sockfd,5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
error("ERROR on accept");
char msg[1024] = "hello";
int len = sizeof(msg);
int xx = sendall(sockfd,(char*)msg,&len);
close(newsockfd);
close(sockfd);
return 0;
}
client code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include<errno.h>
void error(const char *msg)
{
perror(msg);
exit(0);
}
/* receives all data - modelled after sendall() */
int recvall(int s, char *buf, int *len, int timeout)
{
int total=0;
int bytesleft=*len;
int n=0;
time_t start_time;
time_t current_time;
/* clear the receive buffer */
bzero(buf,*len);
time(&start_time);
/* receive all data */
while(total<*len)
{
/* receive some data */
n=recv(s,buf+total,bytesleft,0);
/* no data has arrived yet (non-blocking socket) */
if(n==-1 && errno==EAGAIN)
{
time(&current_time);
if(current_time-start_time>timeout)
break;
sleep(1);
continue;
}
/* receive error or client disconnect */
else if(n<=0)
break;
/* apply bytes we received */
total+=n;
bytesleft-=n;
}
/* return number of bytes actually received here */
*len=total;
/* return <=0 on failure, bytes received on success */
return (n<=0)?n:total;
}
int main(int argc, char *argv[])
{
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[1024];
if (argc < 3)
{
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");;
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
int m = 1024;
n = recvall(sockfd, buffer,&m,10);
if (n < 0)
error("ERROR reading from socket");
printf("%s\n",buffer);
close(sockfd);
return 0;
}

'int xx = sendall(sockfd,(char*)msg,&len);'
'sockfd' is the server listening socket. You should be calling sendall() with 'newsockfd', as returned by the accept() call.

Related

TCP/IP : Transmission not working after string operations

I'm trying to simulate a simple TCP connection between a client and a server, on the localhost. Things are working well without line 22 on "client.c" file, where I'm doing a string operation. With that line un-commented, the server apparently does not make the connection with the client.
I've been searching around for quite long, but I found nothing strictly related to this. It'd be great if I got some help. :)
Files:
client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <unistd.h>
#define BUFLEN 256
void error(char *msg)
{
perror(msg);
exit(0);
}
int main(int argc, char *argv[])
{
int sockfd, n;
//char filename[] = "file.txt"; // !!THE PROBLEM IS HERE!!
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[BUFLEN];
if (argc < 3) {
fprintf(stderr,"Usage %s server_address server_port\n", argv[0]);
exit(0);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(atoi(argv[2]));
inet_aton(argv[1], &serv_addr.sin_addr);
if (connect(sockfd,(struct sockaddr*) &serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
while(1) {
memset(buffer, 0 , BUFLEN);
fgets(buffer, BUFLEN-1, stdin);
n = send(sockfd,buffer,strlen(buffer), 0);
if (n < 0)
error("ERROR writing to socket");
}
return 0;
}
server.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define MAX_CLIENTS 5
#define BUFLEN 256
void error(char *msg)
{
perror(msg);
exit(1);
}
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno, clilen;
char buffer[BUFLEN];
struct sockaddr_in serv_addr, cli_addr;
int n, i, j;
fd_set read_fds;
fd_set tmp_fds;
int fdmax;
if (argc < 2) {
fprintf(stderr,"Usage : %s port\n", argv[0]);
exit(1);
}
FD_ZERO(&read_fds);
FD_ZERO(&tmp_fds);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
portno = atoi(argv[1]);
memset((char *) &serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(struct sockaddr)) < 0)
error("ERROR on binding");
listen(sockfd, MAX_CLIENTS);
FD_SET(sockfd, &read_fds);
fdmax = sockfd;
// main loop
while (1) {
tmp_fds = read_fds;
if (select(fdmax + 1, &tmp_fds, NULL, NULL, NULL) == -1)
error("ERROR in select");
for(i = 0; i <= fdmax; i++) {
if (FD_ISSET(i, &tmp_fds)) {
if (i == sockfd) {
clilen = sizeof(cli_addr);
if ((newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen)) == -1) {
error("ERROR in accept");
}
else {
FD_SET(newsockfd, &read_fds);
if (newsockfd > fdmax) {
fdmax = newsockfd;
}
}
printf("New connection from IP %s, port %d, socket_client %d\n ", inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port), newsockfd);
}
else {
memset(buffer, 0, BUFLEN);
if ((n = recv(i, buffer, sizeof(buffer), 0)) <= 0) {
if (n == 0) {
printf("selectserver: socket %d hung up\n", i);
} else {
error("ERROR in recv");
}
close(i);
FD_CLR(i, &read_fds);
}
else { //recv > 0
printf ("I received from the client with socket %d, this message: %s\n", i, buffer);
}
}
}
}
}
close(sockfd);
return 0;
}
Compiling:
gcc client.c -o client
gcc server.c -o server
Running (in different terminals):
./server 9999
./client localhost 9999

I want to include a for loop in the code below which can continuously send data id, timestamp and message at interval of every n seconds

This is the client program where the intended for loop has to be set. But i am not able to understand where to include it as i am new to socket programming. Please someone help me code it. I need this code to include a loop which will help me continuously transfer random data to the server in every n seconds.
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
void error(char *msg)
{
perror(msg);
exit(0);
}
int main(int argc, char *argv[])
{
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[256];
if (argc < 3) {
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
printf("Please enter the message: ");
bzero(buffer,256);
fgets(buffer,255,stdin);
n = write(sockfd,buffer,strlen(buffer));
if (n < 0)
error("ERROR writing to socket");
bzero(buffer,256);
n = read(sockfd,buffer,255);
if (n < 0)
error("ERROR reading from socket");
printf("%s\n",buffer);
return 0;
}
Add #include<time.h> at the beggining.
Use the function given below to add delay.
void delay(unsigned short secs)
{
unsigned milli_seconds = 1000 * secs;
clock_t start_time = clock(); //declaration in time.h
while (clock() < start_time + milli_seconds)
;
}
Inside main() call the delay(interval) in infinite loop to send timestamp, id and
int main(int argc, char *argv[])
{
unsigned data_id=0;
char data[1024];
...
while(1)
{
delay(5);
send(client_sock,data,strlen(data),0);
}
..
return EXIT_SUCCESS;
}
I hope you get it.
Note: Do not use bzero() instead use memset(). For more read this one.

Issue using c sockets with threads to read from and write to the socket

I want to write a TCP server-client chat, but when I start the two threads for reading from and writing to a socket at both sides, I think they block each other out. Can anyone help me with this?
Server Code:
/* A simple server in the internet domain using TCP the port number is passed as an argument */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>
struct server_args_runner{
char buffer [256];
int newsockfd;
pthread_t tid;
pthread_attr_t attr;
//read/write attribute (read == 0 and write == 1)
int rw;
};
void error(char *msg){
perror(msg);
exit(1);
}
void* server_runner_fun(void* args){
// this is the chat part!
// get args:
int n;
struct server_args_runner *sar = (struct server_args_runner*) args;
if(sar->rw == 0){
printf("server thread trys to read from socket...\n");
//read-part
while(1){
bzero(sar->buffer, 256);
n = read(sar->newsockfd, sar->buffer, 255);
if (n < 0){
error("ERROR reading from socket");
}
}
printf("%s\n", sar->buffer);
} else {
printf("server thread trys to write to socket...\n");
//write-part
while(1){
bzero(sar->buffer, 256);
fgets(sar->buffer, 255, stdin);
n = write(sar->newsockfd, sar->buffer, strlen((char *) &(sar->buffer)));
if (n < 0){
error("ERROR writing to socket");
}
}
}
}
int main(int argc, char *argv[]){
//fd = filedescriptor
int sockfd, portno, clilen;
struct sockaddr_in serv_addr, cli_addr;
int n;
if (argc < 2){
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
//socket(...) returns a descriptor
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1){
error("ERROR opening socket");
}
printf("Socket created successfully.\n");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
//htons(..) converts the short from hostbyteorder to networkbyteorder
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr,sizeof(serv_addr)) == -1){
error("ERROR on binding");
}
printf("binding successfull on port %d\n", portno);
listen(sockfd, 2);
clilen = sizeof(cli_addr);
printf("server is listening ...\n");
struct server_args_runner server_write_t, server_read_t;
server_write_t.newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr, &clilen);
printf("server accepted connection to client.\n");
if (server_write_t.newsockfd < 0){
error("ERROR on accept");
}
//initializing both server_threads
pthread_attr_init(&server_write_t.attr);
pthread_attr_init(&server_read_t.attr);
server_write_t.rw = 1;
server_read_t.rw = 0;
bcopy(&server_write_t.newsockfd, &server_read_t.newsockfd, sizeof(server_write_t.newsockfd));
pthread_create(&server_write_t.tid, &server_write_t.attr, server_runner_fun, &server_write_t);
pthread_create(&server_read_t.tid, &server_read_t.attr, server_runner_fun, &server_read_t);
pthread_join(server_write_t.tid, NULL);
pthread_join(server_read_t.tid, NULL);
return 0;
}
Client code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <pthread.h>
struct client_args_runner{
char buffer [256];
int sockfd;
pthread_t tid;
pthread_attr_t attr;
//read/write attribute (read == 0 and write == 1)
int rw;
};
void error(char *msg){
perror(msg);
exit(0);
}
void* client_runner_fun(void* args){
// this is the chat part!
// get args:
int n;
struct client_args_runner *car = (struct client_args_runner*) args;
if(car->rw == 0){
printf("client thread trys to read from socket...\n");
//read-part
while(1){
bzero(car->buffer, 256);
n = read(car->sockfd, car->buffer, 255);
if (n < 0){
error("ERROR reading from socket");
}
}
printf("%s\n", car->buffer);
} else {
printf("client thread trys to write to socket...\n");
//write-part
while(1){
bzero(car->buffer, 256);
fgets(car->buffer, 255, stdin);
n = write(car->sockfd, car->buffer, strlen((char *) &(car->buffer)));
if (n < 0){
error("ERROR writing to socket");
}
}
}
}
int main(int argc, char *argv[]){
int portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
if (argc < 3){
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
struct client_args_runner client_write_t, client_read_t;
client_write_t.sockfd = socket(AF_INET, SOCK_STREAM, 0);
bcopy(&client_write_t.sockfd, &client_read_t.sockfd,
sizeof(client_write_t.sockfd));
if (client_write_t.sockfd == -1){
error("ERROR on creating socket_file_descriptor");
}
printf("socket created successfully.\n");
server = gethostbyname(argv[1]);
printf("hostname is valid.\n");
if(server == NULL){
fprintf(stderr, "Error, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *) server->h_addr, (char *) &serv_addr.sin_addr.s_addr, server->h_length);
serv_addr.sin_port = htons(portno);
printf("before connecting to client..\n");
if (connect(client_write_t.sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) == -1){
error("ERROR connecting");
}
printf("client connected successfully to server.\n");
//initializing both client_threads
pthread_attr_init(&client_write_t.attr);
pthread_attr_init(&client_read_t.attr);
client_write_t.rw = 1;
client_read_t.rw = 0;
pthread_create(&client_write_t.tid, &client_write_t.attr, client_runner_fun, &client_write_t);
pthread_create(&client_read_t.tid, &client_read_t.attr, client_runner_fun, &client_read_t);
pthread_join(client_write_t.tid, NULL);
pthread_join(client_read_t.tid, NULL);
return 0;
}
Your printfs in both the client and server readers are outside the while(1) loops, so your client and server are communicating fine, you just aren't printing anything you read from the sockets.

variable length message over tcp

I am trying to send variable length message in TCP but the message length that
is printed is always 0. I am using beej guide code for send and receive and pack and unpack to send the header length.Can someone please point out the mistake.
server code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define MAX_SIZE 50
void error(const char *msg)
{
perror(msg);
exit(1);
}
void packi32(unsigned char *buf, unsigned long i)//from beej guide
{
*buf++ = i>>24; *buf++ = i>>16;
*buf++ = i>>8; *buf++ = i;
}
/* sends all data - thanks to Beej's Guide to Network Programming */
int sendall(int s, char *buf, int *len)
{
int total=0;
int bytesleft=*len;
int n=0;
/* send all the data */
while(total<*len){
/* send some data */
n=send(s,buf+total,bytesleft,0);
/* break on error */
if(n==-1)
break;
/* apply bytes we sent */
total+=n;
bytesleft-=n;
}
/* return number of bytes actually send here */
*len=total;
/* return -1 on failure, 0 on success */
return n==-1?-1:0;
}
int sendus(int s,char *msg)
{
char buf[4];//here 4 is header length
int len = strlen(msg);
packi32(buf,len);
int ll = 4;// ll is header length containing message length
int x;
if((x = sendall(s,buf,&ll))< 0)
printf("value of sent x %d\n",x);
int y = sendall(s,msg,&len);
return y;
}
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno;
socklen_t clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;
if (argc < 2)
{
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
error("ERROR on binding");
listen(sockfd,5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
error("ERROR on accept");
char msg[1024] = "hello";
int xx = sendus(sockfd,(char*)msg);
close(newsockfd);
close(sockfd);
return 0;
}
client code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include<errno.h>
void error(const char *msg)
{
perror(msg);
exit(0);
}
/** unpacki32() -- unpack a 32-bit int from a char buffer (like ntohl())
*/
unsigned long unpacki32(unsigned char *buf)
{
return (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
}
/* receives all data - modelled after sendall() */
int recvall(int s, char *buf, int *len, int timeout){
int total=0;
int bytesleft=*len;
int n=0;
time_t start_time;
time_t current_time;
/* clear the receive buffer */
bzero(buf,*len);
time(&start_time);
/* receive all data */
while(total<*len){
/* receive some data */
n=recv(s,buf+total,bytesleft,0);
/* no data has arrived yet (non-blocking socket) */
if(n==-1 && errno==EAGAIN){
time(&current_time);
if(current_time-start_time>timeout)
break;
sleep(1);
continue;
}
/* receive error or client disconnect */
else if(n<=0)
break;
/* apply bytes we received */
total+=n;
bytesleft-=n;
}
/* return number of bytes actually received here */
*len=total;
/* return <=0 on failure, bytes received on success */
return (n<=0)?n:total;
}
int recvme(int s, char *buf)
{
char len[4];
int l = 4;
int n = recvall(s,len,&l,10);
int msg_len = unpacki32(len);
printf("msg_length :%d",msg_len);
int z ;
z = recvall(s,buf,&msg_len,10);
return z;
}
int main(int argc, char *argv[])
{
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[1024];
if (argc < 3)
{
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname(argv[1]);
if (server == NULL)
{
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
n = recvme(sockfd, buffer);
if (n < 0)
error("ERROR reading from socket");
printf("%s\n",buffer);
close(sockfd);
return 0;
}
The basic cause for the failure is in the server's line
int xx = sendus(sockfd,(char*)msg);
- sockfd is the listen() socket, but we have to use the newsockfd returned from accept(), i. e.
sendus(newsockfd, msg);

Simple TCP server with multiple clients C/unix

I'm having problems understanding socket programming and need some help. I am suppose to modify my server code that I have written to accept 3 clients. I know I am suppose to use a fork for each client, but I am not sure how to implement this into my code. Here is my original code that I wrote for one client. Any help would be appreciated.
Server:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
void error(const char *msg)
{
perror(msg);
exit(1);
}
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno;
socklen_t clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;
if (argc < 2) {
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0)
error("ERROR on binding");
listen(sockfd,5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr,
&clilen);
if (newsockfd < 0)
error("ERROR on accept");
bzero(buffer,256);
n = read(newsockfd,buffer,255);
if (n < 0) error("ERROR reading from socket");
printf("Here is the message: %s\n",buffer);
n = write(newsockfd,"I got your message",18);
if (n < 0) error("ERROR writing to socket");
close(newsockfd);
close(sockfd);
return 0;
}
Client:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
void error(const char *msg)
{
perror(msg);
exit(0);
}
int main(int argc, char *argv[])
{
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[256];
if (argc < 3) {
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
//printf("h_addr: %s\n", inet_ntoa(serv_addr.sin_addr));
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
printf("Please enter the message: ");
bzero(buffer,256);
fgets(buffer,255,stdin);
n = write(sockfd,buffer,strlen(buffer));
if (n < 0)
error("ERROR writing to socket");
bzero(buffer,256);
n = read(sockfd,buffer,255);
if (n < 0)
error("ERROR reading from socket");
printf("%s\n",buffer);
close(sockfd);
return 0;
}
Here is your's modified server code to handle multiple clients using fork
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
void error(const char *msg) {
perror(msg);
exit(1);
}
int main(int argc, char *argv[]) {
int sockfd, newsockfd, portno;
socklen_t clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;
if (argc < 2) {
fprintf(stderr, "ERROR, no port provided\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
error("ERROR on binding");
listen(sockfd, 5);
clilen = sizeof(cli_addr);
//Below code is modified to handle multiple clients using fork
//------------------------------------------------------------------
int pid;
while (1) {
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
error("ERROR on accept");
//fork new process
pid = fork();
if (pid < 0) {
error("ERROR in new process creation");
}
if (pid == 0) {
//child process
close(sockfd);
//do whatever you want
bzero(buffer, 256);
n = read(newsockfd, buffer, 255);
if (n < 0)
error("ERROR reading from socket");
printf("Here is the message: %s\n", buffer);
n = write(newsockfd, "I got your message", 18);
if (n < 0)
error("ERROR writing to socket");
close(newsockfd);
} else {
//parent process
close(newsockfd);
}
}
//-------------------------------------------------------------------
return 0;
}
Server.c
#define RUNNING_DIR "/tmp "
define LOCK_FILE "exampled.lock"
#define LOG_FILE "exampled.log"
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <errno.h>
#include <time.h>
#include <string.h>
#define MAXCLIENT 100
#define TRUE 1
#define FALSE 0
#define MINUTE 5
struct Client
{
char name[256];
char *clientAddr;
int fd;
};
int client;
int i;
int minute;
struct Client p[100];
void remove_client(int);
int search_addr(char [],int *);
void log_message(filename,message)
char *filename;
char *message;
{
FILE *logfile;
logfile=fopen(filename,"a");
if(!logfile) return;
fprintf(logfile,"%s\n",message);
fclose(logfile);
}
void catch_int(sig)
int sig;
{
log_message(LOG_FILE,strsignal(sig));
}
void daemonize()
{
int i,lfp,lfp1;
char str[10];
signal(SIGINT, catch_int);
for ( i=0;i<65;i++)
{
if ( i!=32 && i!=33 )
if (signal(i, SIG_IGN) != SIG_IGN)
signal(i, catch_int);
}
if(getppid()==1) return; /* already a daemon */
i=fork();
if (i<0) exit(1); /* fork error */
if (i>0) exit(0); /* parent exits */
/* child (daemon) continues */
setsid(); /* obtain a new process group */
for (i=getdtablesize();i>=0;--i) close(i); /* close all descriptors */
i=open("/dev/null",O_RDWR); dup(i); dup(i); /* handle standart I/O */
umask(027); /* set newly created file permissions */
chdir(RUNNING_DIR); /* change running directory */
lfp=open(LOCK_FILE,O_RDWR|O_CREAT,0640);
lfp1=open(LOG_FILE,O_RDWR|O_CREAT,0640);
if (lfp<0) exit(1); /* can not open */
if (lockf(lfp,F_TLOCK,0)<0) exit(0); /* can not lock */
/* first instance continues */
sprintf(str,"%d\n",getpid());
write(lfp,str,strlen(str)); /* record pid to lockfile */
}
int main()
{
daemonize();
time_t rawtime;
struct tm *info;
time(&rawtime);
info = localtime(&rawtime );
minute=MINUTE + info->tm_min;
int server_sockfd, client_sockfd;
int server_len, client_len;
struct sockaddr_in server_address;
struct sockaddr_in client_address;
int result;
fd_set readfds, testfds;
server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
server_address.sin_port = htons(5000);
server_len = sizeof(server_address);
bind(server_sockfd, (struct sockaddr *)&server_address, server_len);
listen(server_sockfd, 5);
FD_ZERO(&readfds);
FD_SET(server_sockfd, &readfds);
while(1) {
char ch;
int fd;
int nread;
testfds = readfds;
result = select(FD_SETSIZE,&testfds,NULL,NULL,NULL);
if(result < 1) {
perror("server5");
exit(1);
}
for(fd = 0; fd < FD_SETSIZE; fd++) {
time(&rawtime);
info = localtime(&rawtime );
if(FD_ISSET(fd,&testfds)) {
if(fd == server_sockfd) {
int j=0;
char Clients[1096];
memset( Clients, '\0', sizeof(Clients) );
client_len = sizeof(client_address);
client_sockfd = accept(server_sockfd,
(struct sockaddr *)&client_address, &client_len);
client++;
char *sAddress = inet_ntoa(client_address.sin_addr);
p[i].clientAddr=strdup(sAddress);
sprintf(p[i].name,"client%d",client);
p[i].fd=client_sockfd;
for (j =0; j < client; j++)
{
strcat(Clients,p[j].clientAddr);
strcat(Clients," ");
strcat(Clients,p[j].name);
strcat(Clients,"\n");
}
for ( j=0; j < client ; j++)
{
send(p[j].fd,Clients,strlen(Clients),0);
}
i++;
FD_SET(client_sockfd, &readfds);
}
else {
ioctl(fd, FIONREAD, &nread);
if(nread == 0) {
close(fd);
remove_client(fd);
FD_CLR(fd, &readfds);
}
else {
char addr[100];
char *msg;
char sucess[]="Message from Ip Address:";
int n;
int des=0;
int found;
n=recv(fd,addr,sizeof(addr),0);
addr[n]='\0';
strtok_r (addr, "\n", &msg);
found=search_addr(addr,&des);
if ( found )
{
strcat(sucess,addr);
send(fd,"Message Has been
sucessfully sended\n",36,0);
strcat(sucess,"\n");
strcat(sucess,msg);
send(des,sucess,strlen(sucess),0);
}
else
{
send(fd,"Message Sending Failed..\n",27,0);
}
sleep(5);
}
}
}
if ( minute == info->tm_min)
{
int j=0;
char Clients[1096];
memset( Clients, '\0', sizeof(Clients) );
sprintf(Clients,"Now Currently Available ip:\n");
for (j =0; j < client; j++)
{
strcat(Clients,p[j].clientAddr);
strcat(Clients," ");
strcat(Clients,p[j].name);
strcat(Clients,"\n");
}
for ( j=0; j < client ; j++)
{
send(p[j].fd,Clients,strlen(Clients),0);
}
minute=minute+MINUTE;
}
}
}
}
void remove_client(int fd)
{
int j=0;
int pos;
for ( j=0; j< client ; j++)
{
if ( p[j].fd == fd )
{
pos=j;
break;
}
}
for ( j=pos+1 ; j < client ; j++)
{
sscanf( p[j].name, "%s",p[pos].name);
p[pos].clientAddr=p[j].clientAddr;
p[pos].fd=p[j].fd;
pos++;
}
client--;
i--;
}
int search_addr(char address[],int *des)
{
char *name;
int j;
char temp_addr[100];
strcpy(temp_addr,address);
strtok_r (temp_addr, " ", &name);
for ( j=0; j< client ; j++ )
{
if ( (strcmp(temp_addr,p[j].clientAddr)==0) && (strcmp(name,p[j].name)==0))
{
*des=p[j].fd;
return TRUE;
}
}
return FALSE;
}
Client.c
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
// #define SERVERIP "192.168.12.61"
#define PORT 5000
#include <setjmp.h>
#define MAXSLEEP 128
int main(int argc, char *argv[])
{
int Response=1;
int sockfd = 0, n = 0;
char recvBuff[1024];
struct sockaddr_in serv_addr;
jmp_buf env;
if(argc != 2)
{
printf("\n Usage: %s <ip of server> \n",argv[0]);
return 1;
}
memset(recvBuff, '0',sizeof(recvBuff));
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Error : Could not create socket \n");
return 1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
if(inet_pton(AF_INET, argv[1], &serv_addr.sin_addr)<=0)
{
printf("\n inet_pton error occured\n");
return 1;
}
setjmp(env);
if (connect_retry ( sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr) )< 0 )
{
printf("Time Limited Exceeded....\n ");
return 0;
}
for (;;) {
char str[100];
char addr[100];
if ( Response == 1 )
{
int z = recv(sockfd,recvBuff,sizeof(recvBuff),0); //MSG_DONTWAIT
if ( z == -1 )
{
}
else if ( z == 0 )
{
printf("Server Failed ....\n");
longjmp(env, 2);
break;
}
else
{
recvBuff[z] = 0;
printf("'%s'",recvBuff);
sleep(1);
}
}
else
{
int z = recv(sockfd,recvBuff,sizeof(recvBuff),MSG_DONTWAIT); //MSG_DONTWAIT
if ( z == -1 )
{
}
else if ( z == 0 )
{
printf("Server Failed...\n");
longjmp(env, 2);
break;
}
else
{
recvBuff[z] = 0;
printf("'%s'",recvBuff);
sleep(1);
}
}
fd_set rfdset;
FD_ZERO(&rfdset);
struct timeval tv;
tv.tv_sec = 10;
tv.tv_usec = 0;
FD_SET(STDIN_FILENO, &rfdset);
int bReady = select(STDIN_FILENO+1,&rfdset,NULL,NULL,&tv);
if (bReady > 0)
{
// printf("Chat with Client Address: \n");
if( fgets (addr, 4096, stdin)!=NULL ) {
}
printf("Enter Message:\n");
if( fgets (str, 4096, stdin)!=NULL ) {
}
strcat(addr,str);
send(sockfd,addr,strlen(addr),0);
}
Response=0;
}
return 0;
}
int
connect_retry(int sockfd, const struct sockaddr *addr, socklen_t alen)
{
int nsec;
/*
* * Try to connect with exponential backoff.
* */
for (nsec = 1; nsec <= MAXSLEEP; nsec <<= 1) {
if (connect(sockfd, addr, alen) == 0) {
/*
* * Connection accepted.
* */
return(0);
}
/*
* * Delay before trying again.
* */
printf("Waiting For Server....\n");
if (nsec <= MAXSLEEP/2)
sleep(nsec);
}
return(-1);
}
server send the ipaddress of new client connection and each few minutes
192.168.12.61 client1
ENter the msg
Hello

Resources