基于TCP协议服务器(线程/多进程)

基于TCP协议的服务器,线程,多进程版本。
为了解决服务器可以同时和多个客户端数据交互。

代码如下:
server.c

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


typedef struct {
    int sock;
    int a;
}net_info;

void service(int sock,int a)
{
    char buf[1024];
    while(1)
    {
        buf[0] = 0;
        ssize_t s = read(sock,buf,sizeof(buf)-1);
        if(s > 0)
        {
            buf[s] = 0;
            printf("我是 %d : %s\n",a,buf);
            write(sock,buf,strlen(buf));
        }
        else if(s ==0)
        {
            printf("client %d  quit\n",a);
            break;
        }
        else{
            printf("read error!\n");
            break;
        }
    }
}

//线程处理函数
void *rout(void *arg)
{
    net_info* tmp = (net_info*)arg;
    service(tmp->sock,tmp->a);


    close(tmp->sock);
    free(tmp);
}


//./server 0 8080 
int main(int argc,char *argv[])
{
    if(argc != 3)
    {
        printf("usage: ./client [ip]  [port]");
        return 1;
    }
    //创建文件描述符
    int sock  = socket(AF_INET,SOCK_STREAM,0);
    if(sock < 0)
    {
        printf("create socket error\n");
        return 2;
    }

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

    //绑定文件描述符,IP/PORT
    if(bind(sock,(struct sockaddr*)&server_socket,sizeof(struct sockaddr_in))<0)
    {
        printf("bind error\n");
        goto END;
    }


    int ret = listen(sock,5);
    if(ret < 0)
    {
        printf("listen error\n");
        goto END;
    }
    printf("bind and listen success..\n");

    struct sockaddr_in peer;
    while(1)
    {
        socklen_t len = sizeof(peer);
        int new_sock = accept(sock,(struct sockaddr*)&peer,&len);
        if(new_sock<0)
        {
            printf("accept error\n");
            continue;
        }

        net_info *info = (net_info *)malloc(sizeof(net_info));
        if(info == 0)
        {
            perror("malloc\n");
            close(new_sock);
            continue;
        }
        info->sock = new_sock;
        info->a = new_sock;
        //线程
        pthread_t tid;
        pthread_create(&tid,NULL,rout,(void *)info);
        pthread_detach(tid);




/*
        // 多进程
        pid_t pid = fork();
        if(pid == 0)
        {
            //child
            close(sock);

            if(fork() > 0)
            {
                exit(0);
            }
            service(new_sock,a);
            close(new_sock);
            exit(0);
        }
        else if(pid > 0)
        {
            close(new_sock);
            waitpid(pid,NULL,0);
        }
        else{
            printf("fork error\n");
            continue;
        }
      */ 
   }

END:
    close(sock);
    return 0;

}

运行结果:
这里写图片描述

支持多个客户端同时访问。

猜你喜欢

转载自blog.csdn.net/Shawei_/article/details/81586434