多线程并发服务器C++实现字符串小写到大写转换

多线程并发服务器
在这里插入图片描述
在使用线程模型开发服务器时需考虑以下问题:
4. 调整进程内最大文件描述符上限
5. 线程如有共享数据,考虑线程同步
6. 服务于客户端线程退出时,退出处理。(退出值,分离态)
7. 系统负载,随着链接客户端增加,导致其它线程不能及时得到CPU

server.cpp

#include <iostream>
#include <strings.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <ctype.h>
#include <fcntl.h>
#include <assert.h> 
using namespace std;
#define MAXLINE 1024
#define SERV_PORT 8000
//定义一个结构体,将地址和端口号绑在一起
struct s_info{
    
    
    struct sockaddr_in cliaddr;
    int connfd;
};

void *do_work(void *arg){
    
    
    int n,i;
    struct s_info *ts = (struct s_info*)arg;//强制类型转换
    char buf[MAXLINE];
    char str[INET_ADDRSTRLEN];

    while(1){
    
    
        n = read(ts->connfd,buf,MAXLINE);
        if(n == 0){
    
    
            cout << "the client " << ts->connfd << " closed..." << endl;
            break;
        }
        cout << "received from "
            << inet_ntop(AF_INET,&(*ts).cliaddr.sin_addr,str,sizeof(str))
            << " PORT "
            << ntohs((*ts).cliaddr.sin_port)
            << endl;
        for(i = 0;i < n;i++){
    
    
            buf[i] = toupper(buf[i]);
        }
        write(STDOUT_FILENO,buf,n);
        write(ts->connfd,buf,n);
    }
    close(ts->connfd);
    return NULL;
    //return (void*)0;
}

int main(){
    
    
    struct sockaddr_in servaddr,cliaddr;
    struct s_info ts[256];
    socklen_t cliaddr_len = sizeof(cliaddr);

    int listenfd = socket(AF_INET,SOCK_STREAM,0);
    assert(listenfd >= 0);
    
    bzero(&servaddr,sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(SERV_PORT);
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    int ret = bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr));
    assert(ret != -1);

    ret = listen(listenfd,128);
    assert(ret != -1);

    cout << "Accepting client connect ..." << endl;
    int i = 0;
    while(1){
    
    
        int connfd = accept(listenfd,(struct sockaddr*)&cliaddr,&cliaddr_len);
        ts[i].cliaddr = cliaddr;
        ts[i].connfd = connfd;

        //达到线程最大数时,pthread_create出错处理,增加服务器稳定性
        pthread_t tid;
        pthread_create(&tid,NULL,do_work,(void*)&ts[i]);
        pthread_detach(tid);
        i++;
    }

    return 0;
}

client.cpp

#include <iostream>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <assert.h>
#include <strings.h>
#include <string.h>
using namespace std;
#define SERV_PORT 8000
#define MAXLINE 4096
int main(){
    
    
    
    struct sockaddr_in servaddr;
    char buf[MAXLINE];

    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    assert(sockfd >= 0);

    bzero(&servaddr,sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(SERV_PORT);
    inet_pton(AF_INET,"127.0.0.1",&servaddr.sin_addr);
    
    int ret = connect(sockfd,(struct sockaddr*)&servaddr,sizeof(sockaddr));
    if(ret < 0){
    
    
        perror("connect error ");
        exit(1);
    }
	
    while(fgets(buf,MAXLINE,stdin) != NULL){
    
    //读取键盘数据
        write(sockfd,buf,strlen(buf));//将数据写到服务器
        int n = read(sockfd,buf,MAXLINE);//从服务器读取数据
        if(n == 0){
    
    
            cout << "the other side has been closed" << endl;
            break;
        }else{
    
    
            write(STDOUT_FILENO,buf,n);//将从服务器读到的数据显示到客户端屏幕上
        }
    }
    close(sockfd);

    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44515978/article/details/119843868