多线程客户端-服务器模型

时间:2021-02-02 00:18:15

多线程服务器 -- 实现字符回射

服务器端

/*************************************************************************
* File Name: echoservert.c
* Author: Chen WenKe
* Email: chenwenke666@gmail.com
* Blog: https://caotanxiaoke.github.io
* Created Time: Tue 20 Jun 2017 04:18:28 AM PDT
*
* Description: 
 基于多线程的 服务器-客户端 回射 
 ************************************************************************/

#include "csapp.h"

void echo(int connfd);
void *thread(void *vargp);

int main(int argc, char **argv)
{
    int listenfd, *connfdp, port; 
    socklen_t clientlen = sizeof(struct sockaddr_in);
    struct sockaddr_in clientaddr; 
    pthread_t tid;

    if (argc != 2)
    {
        fprintf(stderr, "usage: %s <port>\n", argv[0]); 
        exit(0); 
    }
    port = atoi(argv[1]); 
    listenfd = Open_listenfd(port);
    while(1)
    {
        connfdp = malloc(sizeof(int));   // 避免竞争
        *connfdp = Accept(listenfd, (SA*) &clientaddr, &clientlen);
        Pthread_create(&tid, NULL, thread, connfdp); 
    }
}

// Thread rountine
void *thread(void *vargp)
{
    int connfd = *((int *)vargp);
    Pthread_detach(pthread_self());
    free(vargp);
    echo(connfd);
    Close(connfd); 
    return NULL;
}

// echo
void echo(int connfd)
{
    int n; 
    char buf[MAXLINE]; 
    rio_t rio;

    Rio_readinitb(&rio, connfd);
    while (( n = Rio_readlineb(&rio, buf, MAXLINE)) != 0)
    {
        printf("server received %d bytes\n", n); 
        Rio_writen(connfd, buf, n); 
    }
}




客户端
/*************************************************************************
* File Name: echoclient.c
* Author: Chen WenKe
* Email: chenwenke666@gmail.com
* Blog: https://caotanxiaoke.github.io
* Created Time: Sun 18 Jun 2017 08:00:49 PM PDT
*
* Description: 
 
 ************************************************************************/

#include "csapp.h"

int main(int argc, char **argv)
{
    int clientfd, port; 
    char *host, buf[MAXLINE];
    rio_t rio;

    if (argc != 3)
    {
        fprintf(stderr, "usage: %s <host> <port>\n", argv[0]);
        exit(0); 
    }
    host = argv[1]; 
    port = atoi(argv[2]);

    clientfd = Open_clientfd(host, port); 
    Rio_readinitb(&rio, clientfd); 

    while (Fgets(buf, MAXLINE, stdin) != NULL)
    {
        Rio_writen(clientfd, buf, strlen(buf)); 
        Fputs(buf, stdout); 
    }
    Close(clientfd);
   exit(0);
}





上面代码中所使用的头文件及编译方法