#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string.h>
// gcc -g ThreadsServer.c -lpthread -o ThreadsServer
struct SockInfo{
struct sockaddr_in addr; //地址信息
int fd; //描述符
};
struct SockInfo infos[1024];
void* working(void* arg);
int main()
{
int fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd == -1){
perror("socket err");
return -1;
}
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(9898);
saddr.sin_addr.s_addr = INADDR_ANY;
int ret = bind(fd, (struct sockaddr*)&saddr, sizeof(saddr));
if(ret == -1){
perror("bind err");
return -1;
}
if(listen(fd, 3) != 0){
perror("listen err");
close(fd);
return -1;
}
int max = sizeof(infos)/ sizeof(infos[0]);
int i;
for(i=0; i< max; ++i){
//memset(&infos[i], 0, sizeof(infos[i]));
bzero(&infos[i], sizeof(infos[i]));
infos[i].fd = -1;
}
int addrlen = sizeof(struct sockaddr_in);
while(1){
struct SockInfo *pinfo;
for(i = 0; i < max; i++){
if(infos[i].fd == -1){
pinfo = &infos[i];
break;
}
}
int cfd = accept(fd, (struct sockaddr*)&pinfo->addr, (socklen_t*)&addrlen);
pinfo->fd = cfd;
if (cfd == -1){
perror("accept err");
continue; //继续下一个
}
pthread_t tid;
pthread_create(&tid, NULL, working, pinfo);
//pthread_join(); //是阻塞函数,回收资源
pthread_detach(tid); //
}
close(fd);
return 0;
}
void* working(void* arg){
struct SockInfo* pinfo =(struct SockInfo*)arg;
char ip[32];
printf("连接客户端的IP: %s, 端口: %d \n", inet_ntop(AF_INET, &pinfo->addr.sin_addr.s_addr, ip, sizeof(ip)), ntohs(pinfo->addr.sin_port));
while(1){
char buff[1024], sendBuff[1024];
int len = recv(pinfo->fd, buff, sizeof(buff), 0);
if (len >0){
printf("recv fd: %d client say:%s \n", pinfo->fd, buff);
memcpy(sendBuff, buff, sizeof(buff));
memset(buff, 0, sizeof(buff) );
sprintf(buff, "我收到 fd:%d 的连接了 info: %s \n ",pinfo->fd, sendBuff);
send(pinfo->fd, buff, len, 0);
}
else if(len == 0){
printf("客户端已经断开连接了…… \n");
break;
}
else{
perror("recv err");
break;
}
}
close(pinfo->fd);
pinfo->fd = -1;
return NULL;
}