#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <map>
#include <string>
#include <string.h>
const int port = 8080;
int main()
{
int sock_ser = socket(AF_INET, SOCK_STREAM, 0);
if(sock_ser < 0)
{
perror("socket()");
return -1;
}
sockaddr_in addr_ser;
addr_ser.sin_family = AF_INET;
addr_ser.sin_port = htons(port);
addr_ser.sin_addr.s_addr = INADDR_ANY;
if(bind(sock_ser, (struct sockaddr *)&addr_ser, sizeof(addr_ser))<0)
{
perror("bind()");
return -2;
}
if(listen(sock_ser, 5)<0)
{
perror("listen");
return -3;
}
printf("listening...\n");
std::map<int, std::string> cltlist; //保存服务端和客户端的连接和地址
std::map<int, std::string>::iterator it;
fd_set reads, temps;
int maxfd = sock_ser;
struct sockaddr_in cltaddr;
char buf[1024];
FD_ZERO(&reads);
FD_SET(sock_ser, &reads);
cltlist[sock_ser] = "server";
while(1)
{
struct timeval wait_time = {5,0};
temps = reads;
int fd_count = select(maxfd+1, &temps, NULL, NULL, &wait_time);
if(fd_count < 0)
{
perror("select()");
return -4;
}
if(fd_count==0)
{
printf("timeout\n");
continue;
}
for(it = cltlist.begin();it!=cltlist.end();it++)
{
if(!FD_ISSET(it->first, &temps))
continue;
memset(buf, 0, sizeof(buf));
if(it->first == sock_ser) //检测到新连接
{
socklen_t addr_len = sizeof(cltaddr);
int cltfd = accept(sock_ser, (struct sockaddr *)&cltaddr, &addr_len);
if(cltfd < 0)
{
perror("accept()");
return -5;
}
sprintf(buf, "%s:%d",
inet_ntop(AF_INET, &cltaddr.sin_addr, buf, sizeof(buf)),
ntohs(cltaddr.sin_port));
printf("connected by %s\n", buf);
cltlist[cltfd] = buf;
if(maxfd<cltfd)
maxfd = cltfd;
FD_SET(cltfd, &reads);
}
else //读客户端发过来的信息
{
ssize_t read_s = read(it->first, buf, sizeof(buf));
if(read_s < 0)
{
perror("read()");
return -6
}
else if(read_s == 0)
{
printf("%s leave..\n", it->second.c_str());
FD_CLR(it->first, &reads);
//这里还要删除map中的元素,不过不能在遍历中删,先不做了,
continue;
}
printf("%s say: %s", it->second.c_str(), buf);
}
}
}
close(sock_ser);
return 0;
}
转载于:https://www.cnblogs.com/onestow/p/8214385.html