多线程服务器(简易)

由于单进程服务器只能处理一个客户端,所以引入了多线程,这样便可以处理多客户端,同时还可以锻炼多线程的一些知识,并加以巩固网络编程。

在这里我使用的环境是Linux,windows的不能运行这个程序。

//config.h
#ifndef HEADER_H
#define HEADER_H #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <sys/types.h> #include <unistd.h> #include <errno.h> #include <arpa/inet.h> #include <pthread.h> #include <ctype.h> #define SERVER_IP "127.0.0.1" #define CLIENT_IP "127.0.0.1" #define SERVER_PORT 8887 #endif // HEADER_H
#include "config.h"
//client information
struct clientInfo{
    int socke;
    sockaddr_in sockClient;
};
void *delClient(void *arg){
    char buf[1024];
    clientInfo *client = (clientInfo*)arg;
    printf("new client has connect: ip:%s,port:%d
",inet_ntoa(client->sockClient.sin_addr),htons(client->sockClient.sin_port));
    while(1){
        int n = read(client->socke,buf,1024);
        if(n == 0 || n < 0)
        {
            printf("client %s has error and exit!
",inet_ntoa(client->sockClient.sin_addr));
            return NULL;
        }
        for(size_t i = 0; i < strlen(buf)+1;i++){
            buf[i] = toupper(buf[i]);
        }
        write(client->socke,buf,n);
    }
}
int main(){
    //init socket
    int sockSer, sockClient, i = 0;
    sockaddr_in addrSer,addrCli;
    clientInfo clientinfo[CLIENT_NUM];
    if((sockSer = socket(AF_INET,SOCK_STREAM,0)) == -1){
        perror("socket error:");
        return -1;
    }
    //init addrser
    inet_pton(AF_INET,SERVER_IP,&addrSer.sin_addr.s_addr);
    addrSer.sin_family = AF_INET;
    addrSer.sin_port = htons(SERVER_PORT);

    //bind
    if(0 != bind(sockSer,(sockaddr*)&addrSer,sizeof(addrSer))){
        perror("bind error:");
        return -1;
    }

    //listen
    if(0 != listen(sockSer,CLIENT_NUM)){
        perror("listen error:");
        return 0;
    }
    //acctept
    while (1) {
        int len = sizeof(addrCli);
        sockClient = accept(sockSer,(sockaddr*)&addrCli,(socklen_t*)&len);
        if(sockClient == -1){
            perror("accept error!");
            break;
        }
        //init client msg to thread
        memcpy(&clientinfo[i].sockClient,&addrCli,sizeof(addrCli));
        clientinfo[i].socke = sockClient;

        //create thread
        pthread_t pid;
        pthread_create(&pid,NULL,delClient,(void*)&clientinfo[i]);
        pthread_detach(pid);

    }
    return 0;
}

客户端,可以使用nc命令来链接服务器,例如:

//nc 服务器ip地址 服务器端口号
nc 127.0.0.1 8887 

也可以使用自己写的:

//client.c

#include "config.h"
int main()
{
    int sockSer;
    sockaddr_in addrSer;
    sockSer = socket(AF_INET,SOCK_STREAM,0);
    if(sockSer == -1){
        perror("socket init error: ");
        return -1;
    }
    addrSer.sin_family = AF_INET;
    addrSer.sin_port = htons(SERVER_PORT);
    inet_pton(AF_INET,CLIENT_IP,&addrSer.sin_addr.s_addr);

    if( 0 != connect(sockSer,(sockaddr*)&addrSer,sizeof(sockaddr)))
    {
        perror("connect error:");
        return -1;
    }
    char buf[100];
    while(1){
        scanf("%s",buf);
        write(sockSer,buf,100);
        read(sockSer,buf,100);
        printf("server send back: %s",buf);
    }
}
原文地址:https://www.cnblogs.com/jianmoxiansheng-Guo/p/13237072.html