基於TCP實現的多用戶服務器

1.我們用多進程來實現多用戶的通信

多進程版本——讓子進程的子進程即孫子進程,(子進程如果不等父進程會成爲殭屍進程)


#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/wait.h>

void CreatWorker(int client_fd,struct sockaddr_in* client)
{
    pid_t id=fork();
    if(id<0)
    {
        perror("fork");
        return;
    }
    else if(id==0)//子進程
    {
        if(fork()==0)//孫子進程
        {
            char buf[1024]={0};
            while(1)
            {
                ssize_t s=read(client_fd,buf,sizeof(buf));
                if(s<0)
                {
                    perror("read");
                    continue;
                }
                if(s==0)
                {
                    printf("client close\n");
                    close(client_fd);
                    break;
                }
                buf[s]='\0';
                printf("client %s say :%s\n",inet_ntoa(client->sin_addr),buf);
                write(client_fd,buf,strlen(buf));
            }
        }
        exit(0);
    }
    else
    {
        close(client_fd);
        waitpid(id,NULL,0);
    }
}
int main(int argc,char* argv[])
{
    if(argc!=3)
    {
        printf("./server [ip] [port]\n");
        return 1;
    }

    struct sockaddr_in addr;
    addr.sin_family=AF_INET;
    addr.sin_addr.s_addr=inet_addr(argv[1]);
    addr.sin_port=htons(atoi(argv[2]));

    int sock=socket(AF_INET,SOCK_STREAM,0);
    if(sock<0)
    {
        perror("socket");
        return 2;
    }
    int ret=bind(sock,(struct sockaddr*)&addr,sizeof(addr));
    if(ret<0)
    {
        perror("bind");
        return 3;
    }
    ret=listen(sock,10);
    if(ret<0)
    {
        perror("listen");
        return 4;
    }
    while(1)
    {
        struct sockaddr_in client;
        socklen_t len=sizeof(client);
        int client_fd=accept(sock,(struct sockaddr*)&client,&len);
        if(client_fd<0)
        {
            perror("accept");
            continue;
        }
        CreatWorker(client_fd,&client);
    }
    return 0;
}
2.多線程版本——新線程則執行請求,主線程返會去繼續執行
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<pthread.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/wait.h>



void Request(void* arg)
{
    int client_fd=(int)arg;
    char buf[1024]={0};
    while(1)
    {
        ssize_t s=read(client_fd,buf,sizeof(buf));
        if(s<0)
        {
            perror("read");
            continue;
        }
        else if(s==0)
        {
            printf("client close\n");
            close(client_fd);
            break;
        }
        buf[s]=0;
        printf("client say %s\n",buf);
        write(client_fd,buf,strlen(buf));
    }
    close(client_fd);
    return (void*)0;
}
int main(int argc,char* argv[])
{
    if(argc!=3)
    {
        printf("./server [ip][port]\n");
        return 1;
    }
    struct sockaddr_in addr;
    addr.sin_family=AF_INET;
    addr.sin_port=htons(atoi(argv[2]));
    addr.sin_addr.s_addr=inet_addr(argv[1]);
    
    int sock=socket(AF_INET,SOCK_STREAM,0);
    if(sock<0)
    {
        perror("sock");
        return 1;
    }
    int ret=bind(sock,(struct sockaddr*)&addr,sizeof(addr));
    if(ret<0)
    {
        perror("bind");
        return 1;
    }
    ret=listen(sock,10);
    if(ret<0)
    {
        perror("listen");
        return 1;
    }
    while(1)
    {
        struct sockaddr_in client;
        socklen_t len=sizeof(client);
        int client_fd=accept(sock,(struct sockaddr*)&client,&len);
        if(client_fd<0)
        {
            perror("accept");
            continue;
        }
        pthread_t tid;
        pthread_create(&tid,NULL,Request,(void*)client_fd);
        pthread_detach(tid);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章