使用fork()的多客户端服务器

问题描述:

我正在尝试创建一个套接字编程服务器,以使用fork()同时处理多个客户端。
但是我无法正确实现它。我已经尝试了很长时间。
我面临的问题是
1)地址绑定问题
2)问题如何处理父进程和子进程
3)如何结束服务器程序,即..return到控制台
我的单个客户端服务器程序正常运行。这是多个客户端服务器的代码。

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 long time . The problems I am facing are 1) address bind problem 2) problem how to handle parent process and child process 3) how to end the server program ie ..return to the console My programs for a single client server were working properly.Here is my code for the multiple client-server.

#include<signal.h>
#include<stdio.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<string.h>
#include<sys/types.h>
#include<stdlib.h>

int main()
{

    struct sockaddr_in myaddr ,clientaddr;
    int sockid,newsockid;
    sockid=socket(AF_INET,SOCK_STREAM,0);
    memset(&myaddr,'0',sizeof(myaddr));
    myaddr.sin_family=AF_INET;
    myaddr.sin_port=htons(8888);
    myaddr.sin_addr.s_addr=inet_addr("127.0.0.1");
    if(sockid==-1)
    {
        perror("socket");
    }
    int len=sizeof(myaddr);
    if(bind(sockid,( struct sockaddr*)&myaddr,len)==-1)
    {
        perror("bind");
    }
    if(listen(sockid,10)==-1)
    {
        perror("listen");
    }
    int pid,new;
    static int counter=0;
    for(;;)
    {       a:
            new =accept(sockid,(struct sockaddr *)&clientaddr,&len);

            if(pid=fork()==-1)
            {
                close(new);
                continue;

            }   
            else if(pid>0)
            {
            counter++;
            //wait();
            goto a;
            printf("here2");
            //close(new);
            continue;
            }   
            else if(pid==0)
            {
            counter++;
            printf("here 1");
            send(new,"hi",100,0);
            send(new,(char *) &counter,1,0);

            //kill(pid,SIGKILL);
            //close(new);
            }

    }
    printf("here3");
    close(sockid);
    return 0;
}

这是简单的客户端程序

    #include<stdio.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<string.h>
#include<sys/types.h>


int main()
{

    struct sockaddr_in myaddr ,serveraddr;
    int sockid;
    sockid=socket(AF_INET,SOCK_STREAM,0);
    memset(&myaddr,'0',sizeof(myaddr));
    myaddr.sin_family=AF_INET;
    myaddr.sin_port=htons(8888);
    myaddr.sin_addr.s_addr=inet_addr("127.0.0.1");
    if(sockid==-1)
    {
        perror("socket");
    }
    int len=sizeof(myaddr);
    if(connect(sockid,(const struct sockaddr*)&myaddr,len)==-1)
    {
        perror("connect");
    }
    fprintf(stdout,"Client Online....");
    char s[10000];


        //gets(s);
        //send(sockid,s,10000,0);
        recv(sockid,&s,10000,0);
        fprintf(stdout,"Server says....");
        puts(s);
        recv(sockid,&s,10000,0);
        fprintf(stdout,"Server says....");
        puts(s);

sleep(10);  
    close(sockid);
    return 0;
}

有人可以告诉我我做错了什么,正确的方法是什么去做吧..?任何帮助将不胜感激...

Can someone please tell me what I am doing wrong and what is the correct way to do it..? Any help will be greatly appreciated...

您遇到的主要问题是 == 的优先级高于 = ,因此此行:

The main problem you have is that == has higher precedence than =, so this line:

if(pid=fork()==-1)

分配 fork()== -1 pid ,这不是您想要的:它将始终为 0 fork()成功时,在子代中都成功。您需要使用:

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)

您还应该在 close(new) $ c> fork()-该孩子现在拥有该套接字。如果要发送计数器的文本版本,则需要使用 snprintf()将其转换为文本。孩子也应该在完成后退出-在您的代码中最简单的方法是跳出循环。经过这些更正之后,服务器中的内部循环看起来像:

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;
        }
}