多线程并发服务器
架构
void* thread_fun(void* arg)
{while(1){recv()/send()}
}scokfd = socket()
bind()
listen()
while(1){accept()//连上就创建线程pthread_create(, ,thread_fun, )pthread_detach()
}
案例
/*
# Multi-process concurrent server
# https://www.cnblogs.com/kencszqh
#
# File Name: 多线程并发.c
# Created : 2024/6/11
*/#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/epoll.h>
#include <pthread.h>
#include <semaphore.h>
#include <sys/mman.h>
#include <sys/eventfd.h>
#include <sys/timerfd.h>
#include <sys/signalfd.h>
#include <sys/syscall.h>
#include <sys/prctl.h>
#include <sys/uio.h>#define N 128
#define ERR_LOG(errmsg) \do \{ \perror(errmsg); \exit(1); \} while (0)typedef struct
{struct sockaddr_in addr;int acceptfd;
} MSG;void *pthread_func(void *arg)
{char buf[N] = {0};ssize_t bytes;MSG *msg = (MSG *)arg;while (1){if ((bytes = read(msg->acceptfd, buf, sizeof(buf))) == -1){if (errno == EINTR){continue;}ERR_LOG("read");}else if (bytes == 0){printf("client quit!\n");pthread_exit(NULL);}if (strncmp(buf, "quit", 4) == 0){printf("client quit!\n");pthread_exit(NULL);}printf("[%s - %d]: %s\n", inet_ntoa(msg->addr.sin_addr), ntohs(msg->addr.sin_port), buf);strcat(buf, " ^_^ ");if (send(msg->acceptfd, buf, strlen(buf), 0) == -1){ERR_LOG("fail to send");}}
}int main(int argc, char *argv[])
{if (argc != 3){fprintf(stderr, "Usage:%s [ip] [port]\n", argv[0]);exit(1);}int sockfd, acceptfd;struct sockaddr_in serveraddr, clientaddr;socklen_t addrlen = sizeof(serveraddr);// 1.创建套接字if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){ERR_LOG("socket");}// 2.绑定serveraddr.sin_family = AF_INET;serveraddr.sin_port = htons(atoi(argv[2]));serveraddr.sin_addr.s_addr = inet_addr(argv[1]);if (bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0){ERR_LOG("bind");}// 3.监听if (listen(sockfd, 5) < 0){ERR_LOG("listen");}// 4.接受客户端连接while (1){if ((acceptfd = accept(sockfd, (struct sockaddr *)&clientaddr, &addrlen)) < 0){ERR_LOG("accept");}MSG msg;msg.addr = clientaddr;msg.acceptfd = acceptfd;pthread_t thread;if (pthread_create(&thread, NULL, pthread_func, (void *)&msg) != 0){ERR_LOG("pthread_create");}pthread_detach(thread);}return 0;
}