linuxC 多线程并发服务器

本文介绍了一个使用多线程处理多个客户端连接的简单服务器程序。服务器能够接收来自多个客户端的消息,并将消息转换为大写后回传给客户端。通过创建新的线程来处理每个客户端连接,实现了基本的并发处理。

server.c

/*************************************************************************
    > File Name: server.c
    > Author: Px.W
    > mail: xxxxxxxxx@163.com
    > Created Time: Monday, September 26, 2022 PM04:09:25 CST
 ************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <strings.h>
#include <unistd.h>
#include <ctype.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>

#define SERVER_IP "192.168.245.128"
#define SERVER_PORT 9999
#define MAX_LEN 80

#define prrexit(msg) {\
    perror(msg);\
    exit(1);\
}

void * pthread_fun(void *arg)
{
    pthread_detach( pthread_self() );

    char buf[MAX_LEN];
    int i ;
    int connfd = (int)arg;
    while (1)
    {
        int n = read(connfd , buf , MAX_LEN);
        write(1 , buf , n);
        if( strncmp(buf , "q" , 1) == 0 )
        {
            printf("client %p unconnect.\n" , pthread_self());
            break;
        }

        for(i = 0 ; i < n; i++)
            buf[i] = toupper(buf[i]);
        
        write(connfd , buf , n);
    }
    close(connfd);
    return (void*)0;
}

int main()
{
    int listenfd , connfd;
    struct sockaddr_in serveraddr , clientaddr;
    socklen_t clientaddr_len;
    char ip_str[INET_ADDRSTRLEN];

    listenfd = socket(AF_INET , SOCK_STREAM , 0);
    if(listenfd < 0)
        prrexit("SOCKET");

    bzero(&serveraddr , sizeof(serveraddr));
    serveraddr.sin_port = htons(SERVER_PORT);
    serveraddr.sin_family = AF_INET;
    inet_pton( AF_INET, SERVER_IP , &serveraddr.sin_addr );
    if( (bind(listenfd , (struct sockaddr*)&serveraddr , (socklen_t)sizeof(serveraddr))) < 0)
        prrexit("BIND");

    if( listen(listenfd , 20) < 0 )
        prrexit("LISTEN");

    printf("wait connect... \n");

    while (1)
    {
        clientaddr_len = sizeof(clientaddr);
        if ( (connfd = accept( listenfd , (struct sockaddr*)&clientaddr ,&clientaddr_len )) < 0 )
            prrexit("ACCEPT");

        inet_ntop(AF_INET , &clientaddr.sin_addr , ip_str , INET_ADDRSTRLEN);
        printf("client ip=%s , port=%d \n", ip_str , ntohs(clientaddr.sin_port));

        pthread_t tid;
        pthread_create( &tid , NULL , pthread_fun , (void*)connfd );
        printf("create new thread = %p\n" , tid);
    }

    close(listenfd);
    return 0;
}

client.c

/*************************************************************************
    > File Name: server.c
    > Author: Px.W
    > mail: xxxxxxxxx@163.com
    > Created Time: Monday, September 26, 2022 PM04:09:32 CST
 ************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <strings.h>
#include <unistd.h>
#include <ctype.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>

#define SERVER_IP "192.168.245.128"
#define SERVER_PORT 9999
#define MAX_LEN 80

#define prrexit(msg) {\
    perror(msg);\
    exit(1);\
}

int main()
{
    int fd ; 
    struct sockaddr_in serveraddr;
    char buf[MAX_LEN];

    if( (fd = socket(AF_INET , SOCK_STREAM , 0)) < 0)
        prrexit("SOCKET");

    bzero(&serveraddr , sizeof(serveraddr));
    inet_pton(AF_INET , SERVER_IP , &serveraddr.sin_addr);
    serveraddr.sin_port = htons(SERVER_PORT);
    serveraddr.sin_family = AF_INET;
    if( (connect(fd , (struct sockaddr*)&serveraddr , (socklen_t)sizeof(serveraddr))) < 0)
        prrexit("CONNECT");

    while (1)
    {
        int n = read(0 , buf , MAX_LEN);
        write( fd , buf , n);
        if( !strncmp(buf , "q" , 1) )
        {
            printf("client unconnect.\n");
            break;
        }

        n = read(fd , buf , MAX_LEN);
        write(1 , buf , n);
    }
    close(fd);

    return 0;
}

效果:

一个server可支持处理多个client发来的请求。 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值