I am trying to create a socket programming server to handle multiple clients at the same time using fork().. But I am not able to implement it properly.I have been trying for a
The main problem you have is that ==
has higher precedence than =
, so this line:
if(pid=fork()==-1)
is assigning the result of fork() == -1
to pid
, which isn't what you want: it'll always be 0
when fork()
succeeds, in both the child and the parent. You need to use:
if((pid = fork()) == -1)
You should also close(new)
in the parent after the fork()
- the child owns that socket now. If you want to send the textual version of the counter, you need to use snprintf()
to convert it to text. The child should also exit after it's finished - the easiest way to do that in your code is to break out of the loop. After these corrections, the inner loop in your server looks like:
for(;;)
{
new = accept(sockid, (struct sockaddr *)&clientaddr, &len);
if ((pid = fork()) == -1)
{
close(new);
continue;
}
else if(pid > 0)
{
close(new);
counter++;
printf("here2\n");
continue;
}
else if(pid == 0)
{
char buf[100];
counter++;
printf("here 1\n");
snprintf(buf, sizeof buf, "hi %d", counter);
send(new, buf, strlen(buf), 0);
close(new);
break;
}
}
Try this one might you get solution,
Server Program:
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <signal.h>
#include <unistd.h>
int main()
{
int server_sockfd, client_sockfd;
int server_len, client_len;
struct sockaddr_in server_address;
struct sockaddr_in client_address;
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(9734);
server_len = sizeof(server_address);
bind(server_sockfd, (struct sockaddr *)&server_address,server_len);
/* Create a connection queue, ignore child exit details and wait for
clients. */
listen(server_sockfd, 5);
signal(SIGCHLD, SIG_IGN);
while(1) {
char ch;
printf("server waiting\n");
/* Accept connection. */
client_len = sizeof(client_address);
client_sockfd = accept(server_sockfd,(struct sockaddr *)&client_address, &client_len);
/* Fork to create a process for this client and perform a test to see
whether we're the parent or the child. */
if(fork() == 0) {
/* If we're the child, we can now read/write to the client on
client_sockfd.
The five second delay is just for this demonstration. */
read(client_sockfd, &ch, 1);
sleep(5);
ch++;
write(client_sockfd, &ch, 1);
close(client_sockfd);
exit(0);
}
/* Otherwise, we must be the parent and our work for this client is
finished. */
else {
close(client_sockfd);
}
}
}
Client Program:
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<string.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
void main()
{
int sid;
char s[10]={},s1[10]={};
struct sockaddr_in ssock,csock;
sid=socket(AF_INET,SOCK_STREAM,0);
ssock.sin_family=AF_INET;
ssock.sin_addr.s_addr=inet_addr("127.0.0.1");
ssock.sin_port=htons(9734);
connect(sid,(struct sockaddr *)&ssock,sizeof(ssock));
while(1)
{
printf("\n Enter the string:");
scanf("%s",s);
write(sid,(void*)s,strlen(s));
if(strlen(s)==0)
break;
sleep(1);
read(sid,(void*)s1,sizeof(s1));
printf("\n The received string is:%s\n",s1);
}
close(sid);
}
Here code is doing communication for only one character.