#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define LOG(s) printf("[%s] {%s:%d} %s \n", __DATE__, __FILE__, __LINE__, s);
int server_handler(int server, struct sockaddr_in saveCaddr[])
{
struct sockaddr_in addr = {0};
socklen_t asize = sizeof(addr);
int ret = -1;
if((ret = accept(server, (struct sockaddr*)&addr, &asize)) == -1)
{
LOG("accept error");
perror("accept error");
return -1;
}
printf("[%s/%d] client%d 已连接\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port), ret);
saveCaddr[ret] = addr;
return ret;
}
int client_handler(int client, struct sockaddr_in* saveCaddr)
{
char buf[128] = {0};
bzero(buf, sizeof(buf));
int ret = read(client, buf, sizeof(buf)-1);
if(ret == 0)
{
printf("[%s/%d] client%d 已下线\n", inet_ntoa(saveCaddr[client].sin_addr), ntohs(saveCaddr[client].sin_port), client);
ret = -1;
}
else if(ret > 0)
{
buf[ret] = 0;
printf("[%s/%d] client%d:%s\n", inet_ntoa(saveCaddr[client].sin_addr), ntohs(saveCaddr[client].sin_port), client, buf);
if(strcmp(buf, "quit") != 0)
{
ret = write(client, buf, ret);
}
else
{
printf("[%s/%d] client%d 已下线\n", inet_ntoa(saveCaddr[client].sin_addr), ntohs(saveCaddr[client].sin_port), client);
ret = -1;
}
}
return ret;
}
int main(char argc, char* argv[])
{
int server = 0;
struct sockaddr_in saddr = {0};
int max = 0;
int num = 0;
fd_set reads = {0};
fd_set temps = {0};
server = socket(PF_INET, SOCK_STREAM, 0);
if(server == -1)
{
puts("server socket error");
return -1;
}
int reuse = 1;
if(setsockopt(server, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
{
LOG("setsockopt");
return -1;
}
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
saddr.sin_port = htons(8899);
if(bind(server, (struct sockaddr*)&saddr, sizeof(saddr)) == -1)
{
puts("server bind error");
return -1;
}
if(listen(server, 5) == -1)
{
puts("server listen error");
return -1;
}
puts("server start success");
FD_ZERO(&reads);
FD_SET(server, &reads);
FD_SET(0, &reads);
max = server;
struct sockaddr_in saveCaddr[1024];
while(1)
{
temps = reads;
num = select(max+1, &temps, NULL, NULL, NULL);
if(num > 0)
{
for(int i = 0; i <= max; i++)
{
if(FD_ISSET(i, &temps) == 0)
continue;
if(0 == i)
{
puts("键盘事件");
char buf[128] = "";
bzero(buf, sizeof(buf));
fgets(buf, sizeof(buf), stdin);
buf[strlen(buf) - 1] = 0;
printf("input: %s\n",buf);
}
else if(server == i)
{
puts("连接事件");
int client = server_handler(server, saveCaddr);
if(client > -1)
{
FD_SET(client, &reads);
max = (client > max)? client : max;
}
}
else
{
puts("通信事件");
int r = client_handler(i, saveCaddr);
if(r == -1)
{
FD_CLR(i, &reads);
close(i);
while(FD_ISSET(max, &reads) == 0 && max-- >= 0);
}
}
}
}
}
close(server);
return 0;
}