前言
最近在牛客上学习Linux高并发项目,写一些博文以供记录查看
客户端
发送通过键盘获取的内容给服务器。
#include <stdio.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main(){
int fd = socket(AF_INET, SOCK_STREAM, 0);
if(fd == -1){
perror("socket");
exit(-1);
}
struct sockaddr_in serveraddr;
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(9999);
inet_pton(AF_INET, "192.168.21.129", &serveraddr.sin_addr.s_addr);
int ret = connect(fd, (struct sockaddr*)&serveraddr, sizeof(serveraddr));
if(ret == -1){
perror("connect");
exit(-1);
}
char recvBuf[1024];
int i = 0;
while(1){
//sprintf(recvBuf, "data : %d\n", i++);
scanf("%s", recvBuf);
write(fd, recvBuf, strlen(recvBuf) + 1);
int len = read(fd, recvBuf, sizeof(recvBuf));
if(len == -1){
perror("read");
exit(-1);
}
if(len == 0){
printf("server closed....");
break;
}
if(len > 0){
printf("recv : %s\n", recvBuf);
}
sleep(2);
}
close(fd);
return 0;
}
服务端
建立最大值为128的线程池,也就是说最多可以有128个客户端同时连接服务器,如果超过数量,那么等待1秒后重新查询线程池是否有空的线程,以此达到多线程效果。
#include<stdio.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
struct sockInfo{
int fd;
struct sockaddr_in addr;
pthread_t tid;
};
struct sockInfo sockinfos[128];
void * working(void * arg){
struct sockInfo * pinfo = (struct sockInfo *) arg;
char cliIP[16];
inet_ntop(AF_INET, &pinfo->addr.sin_addr.s_addr, cliIP, sizeof(cliIP));
unsigned short cliPort = ntohs(pinfo->addr.sin_port);
printf("client ip is : %s, prot is %d\n", cliIP, cliPort);
char recvBuf[1024];
while(1){
int len = read(pinfo->fd, &recvBuf, sizeof(recvBuf));
if(len == -1){
perror("read");
return -1;
}
if(len == 0){
printf("client closed....\n");
break;
}
if(len > 0) {
printf("recv client : %s\n", recvBuf);
}
write(pinfo->fd, recvBuf, strlen(recvBuf) + 1);
}
close(pinfo->fd);
return NULL;
}
int main(){
//创建socket套接字
int lfd = socket(PF_INET, SOCK_STREAM, 0);
if(lfd == -1){
perror("socket");
return -1;
}
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(9999);
saddr.sin_addr.s_addr = 0;
//绑定
int ret = bind(lfd, (struct sockaddr *)&saddr, sizeof(saddr));
if(ret == -1){
perror("bind");
return -1;
}
//监听
ret = listen(lfd, 128);
if(ret == -1){
perror("listen");
return -1;
}
int max = sizeof(sockinfos) / sizeof(sockinfos[0]);
bzero(&sockinfos, sizeof(sockinfos));
for(int i = 0; i < max; i++){
sockinfos[i].fd = -1;
sockinfos[i].tid = -1;
}
while(1){
struct sockaddr_in cliaddr;
int len = sizeof(cliaddr);
int cfd = accept(lfd, (struct sockaddr*)&cliaddr, &len);
struct sockInfo * pinfo;
for(int i = 0; i < max; i++){
if(sockinfos[i].fd == -1){
pinfo = &sockinfos[i];
break;
}
if(i == max - 1){
sleep(1);
i = 0;
}
}
pinfo->fd = cfd;
memcpy(&pinfo->addr, &cliaddr, len);
pthread_create(&pinfo->tid, NULL, working, pinfo);
pthread_detach(pinfo->tid);
}
close(lfd);
return 0;
}