使用select进行进行处理
这次博主在上一次的基础上,进行了升级,上个版本是使用单个线程处理,当并发量比较高的时候,比较慢,今天博主进行了升级,使用多线程,当客户端发送请求的时候,当检测到文件描述符符合条件时就会开一个子线程去处理,然后当客户端发送处理时,也会开一个线程,但是最后也别忘记了线程同步,避免数据竞争导致数据混乱,这样可以大大提高速度。
下面是改进后的代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
pthread_mutex_t mutex;
typedef struct fdinfo
{
int fd;
int *maxfd;
fd_set* redset;
}FDInfo;
void* acceptConn(void *arg){
std::cout<<"pd_id: "<fd, NULL, NULL);
pthread_mutex_lock(&mutex);
if (cfd == -1) {
std::cout << "accept error" << std::endl;
exit(1);
}
std::cout << "New client connected: " << std::endl;
FD_SET(cfd, info->redset);
*info->maxfd=std::max(cfd,*info->maxfd);
pthread_mutex_unlock(&mutex);
free(info);
return NULL;
}
void *communication(void *arg){
std::cout<<"pd_id:"<fd, buf, sizeof(buf), 0);
if (len == -1) {
std::cout << "recv error" << std::endl;
exit(1);
free(info);
return NULL;
} else if (len == 0) {
pthread_mutex_lock(&mutex);
FD_CLR(info->fd, info->redset);
close(info->fd);
pthread_mutex_unlock(&mutex);
std::cout << "client is closed" << std::endl;
free(info);
return NULL;
}
// 转换为大写
for (int j = 0; j < len; j++) {
buf[j] = toupper(buf[j]);
std::cout << "alter buf: " << buf[j] << std::endl;
}
int ret = send(info->fd, buf, strlen(buf) + 1, 0);
if (ret == -1) {
std::cout << "send error" << std::endl;
free(info);
return NULL;
}
free(info);
return NULL;
}
int main(int argc, const char* argv[]) {
pthread_mutex_init(&mutex,NULL);
int lfd = socket(AF_INET, SOCK_STREAM, 0); // 创建监听套接字
if (lfd == -1) {
std::cout << "socket error" << std::endl;
exit(0);
}
struct sockaddr_in ser_addr;
memset(&ser_addr, 0, sizeof(ser_addr));
ser_addr.sin_family = AF_INET;
ser_addr.sin_port = htons(8888);
ser_addr.sin_addr.s_addr = htonl(INADDR_ANY);
// 绑定端口
int ret = bind(lfd, (struct sockaddr*)&ser_addr, sizeof(ser_addr));
if (ret == -1) {
std::cout << "bind error" << std::endl;
exit(1);
}
// 监听
ret = listen(lfd, 64);
if (ret == -1) {
std::cout << "listen error" << std::endl;
exit(1);
}
fd_set redset;
FD_ZERO(&redset);
FD_SET(lfd, &redset);
int maxfd = lfd;
while (1) {
pthread_mutex_lock(&mutex);
fd_set tmp = redset;
int ret = select(maxfd + 1, &tmp, NULL, NULL, NULL);
pthread_mutex_unlock(&mutex);
// 处理监听套接字
if (FD_ISSET(lfd, &tmp)) {
pthread_t tid;
FDInfo* info= new FDInfo();
info->fd=lfd;
info->maxfd = &maxfd;
info->redset=&redset;
pthread_create(&tid,NULL,acceptConn,info);
pthread_detach(tid);
}
// 处理客户端套接字
for (int i = 0; i <= maxfd; i++) {
if (i != lfd && FD_ISSET(i, &tmp)) {
pthread_t tid;
FDInfo* info= new FDInfo();
info->fd=i;
info->redset=&redset;
pthread_create(&tid,NULL,communication,info);
pthread_detach(tid);
}
}
}
pthread_mutex_destroy(&mutex);
close(lfd);
return 0;
}
下面是运行结果,客户端会发送一个json文件,他会全部转化为大写返回

博主发送了密码和账号:

可以看到全部转化为大写并发送回去,开了大概8个线程。
今天的更新就到这了。下次见
评论
还没有任何评论,你来说两句吧!