网络编程---多线程/多进程版TCP套接字编程

TCP\IP协议我之后会放在一起进行解释,因为这块较UDP来说比较复杂,我需要分成两三篇博客来分几个部分详谈,如TCP中的三次握手,四次回收,超时重传等,IP协议的底层通信,路由,MAC帧等,都会讲到,我尽量总结点详细一点,以免遗漏。这里我就只放上TCP套接字编程的代码,接口和一些注意的点在之前的TCP/UDP套接字原理中都有讲到,看不懂的请戳这里->链接

大家研究代码的时候也可以与UDP对比着看,链接在这里->UDP原理及套接字编程实现

多线程/多进程版就是为了可以一次性处理多个客户端请求,两者之间也要对比着看:

  • 多进程版
    • 优点
    • 处理多用户请求
    • 稳定性比较强(进程的独立性)
    • 缺点
    • 创建子进程消耗时间,因为是建立连接后才创建
    • 多进程服务器每个进程都吃资源,所以多进程服务器服务的客户是有上限的,而且这个上限较低
    • CPU进行进程切换的周期边长,调度压力变大,会影响性能
  • 多线程版
    • 优点
    • 同样可以处理多用户请求
    • 较多进程:创建新线程时消耗时间较短,吃资源较少,切换成本小
    • 缺点
    • 稳定性较差,可能因为单线程安全问题导致服务器挂掉

两个版本都只使用中小型应用。

我就直接放代码了,有什么不对的点大家记得帮我指出来。

server.c

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

#define MAX 128 

typedef struct Arg{
    int fd;
    struct sockaddr_in addr;
}Arg;

void* Server(void *arg)
{
    Arg* p = (Arg*)arg;
    char buf[MAX];
    while(1)
    {
        buf[0] = 0;
        ssize_t s = read(p->fd,buf,sizeof(buf));
        if(s < 0)
        {
            perror("read");
            continue;
        }else if(s == 0)
        {
            printf("client[%s] quit!\n",inet_ntoa(p->addr.sin_addr));
            close(p->fd);
            break;
                    } 
        buf[s] = 0;
        printf("client[%s] says:%s\n",inet_ntoa(p->addr.sin_addr),buf);
        write(p->fd,buf,strlen(buf));
    }
    return NULL;
}


int main(int argc, char* argv[])
{
    if(argc != 3)
    {
        printf("Usage: [ip] [port]\n");
        exit(1);

    }
    int sock = socket(AF_INET,SOCK_STREAM,0);//socket处于创建状态
    if(sock < 0)
    {
        perror("socket");
        exit(2);
    }

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

    if(bind(sock,(const struct sockaddr*)&server,sizeof(server)) < 0)
    {
        perror("bind");                                                                                                                 
        exit(3);
    }
   listen(sock,5);
    if(sock < 0)//此时处于监听状态
    {
        perror("listen");
        exit(4);
    }
    printf("Bind and listen successed ,waiting for accepting...\n");

    for(;;)
    {
        struct sockaddr_in client;
        socklen_t len = sizeof(client);
        int client_socket = accept(sock,(struct sockaddr*)&client,&len);
        printf("。。。\n");
        if(client_socket < 0)
        {
            continue;
        }
        pthread_t thread;
        Arg* arg;
        arg = (Arg*)malloc(sizeof(arg));
        arg->fd = client_socket;
        arg->addr = client;
        if(pthread_create(&thread,NULL,Server,(void*)arg) == 0)
        {
            perror("pthread_create");
        }
        pthread_detach(thread);//线程分离
//        pid_t son = fork();注释注掉的部分是多进程版本
//        if(son < 0)
//        {
//            perror("fork");
//            return 0;
//        }
//        if(son == 0)
//        {
//            pid_t son_son = fork();
//            if(son_son == 0)
//            {
//                Server(client_socket,&client);
//            }
//            exit(0);
//        }
//        wait(NULL);
    }
    return 0;
}           

client.c

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

#define MAX 128

int main(int argc, char* argv[])
{
    if(argc != 3)
    {   
        printf("Usage: [ip] [port]\n");
        exit(1);
    }   
    int sock = socket(AF_INET, SOCK_STREAM, 0); 
    if(sock < 0)
    {   
        perror("socket");
        exit(2);
    }   

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

    socklen_t len = sizeof(client);
    if(connect(sock,(struct sockaddr*)&client,len) < 0)
    {   
        perror("connect");
        exit(3);
            }

    char buf[MAX];
    printf("connect success....\n");
    while(1)
    {
        printf("Client say#");    
        buf[0] = 0;
        fflush(stdout);
        ssize_t s = read(0,buf,sizeof(buf));
        if(s > 0)
        {
            buf[s-1] = 0;
            write(sock,buf,strlen(buf));
            if(strcmp("quit",buf) == 0)
            {
                printf("connect quit...\n");
                close(sock);
                return 0;
            }
            read(sock,buf,sizeof(buf));                                                                                                 
            fflush(stdout);
            printf("Server reply#%s \n",buf);
        }
    }

    close(sock);

    return 0;
}

猜你喜欢

转载自blog.csdn.net/IT_xiaoye/article/details/80483079
今日推荐