#include "stdafx.h"
using namespace std;
#define PORT 5006 /* Port that will be opened */
#define BACKLOG 5 /* Number of allowed connections */
#define MAXDATASIZE 4096
typedef map<unsigned int,sockaddr_in> socket_maptable_t;
bool process_client(int sockfd,sockaddr_in addr,char* recvbuf, int len);
socket_maptable_t socket_maptable;
int fds[2];
void* dispatch_thread(void *arg)
{
char buf[MAXDATASIZE];
arg = NULL;
pr_debug("fds[0]:%d,fds[1]:%d",fds[0],fds[1]);
while (1)
{
int readed = read(fds[0],buf,MAXDATASIZE);
pr_debug("readed:%d\r\n%s",readed,buf);
}
}
int main()
{
int sock_fd;
ssize_t recv_size;
fd_set read_set;
fd_set all_set;
int listen_fd;
int connect_fd;
int ready_size;
socklen_t addr_size;
sockaddr_in srv_addr;
sockaddr_in addr;
unsigned int max_fd = 0;
int errcode;
char recv_buf[MAXDATASIZE];
if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
pr_debug("Creating socket failed.");
exit(1);
}
int opt = SO_REUSEADDR;
setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
bzero(&srv_addr,sizeof(srv_addr));
srv_addr.sin_family=AF_INET;
srv_addr.sin_port=htons(PORT);
srv_addr.sin_addr.s_addr = htonl (INADDR_ANY);
if (bind(listen_fd, (struct sockaddr *)&srv_addr, sizeof(struct sockaddr)) == -1)
{
pr_debug("Bind error.");
exit(1);
}
if(listen(listen_fd,BACKLOG) == -1)
{
pr_debug("listen() error\n");
exit(1);
}
//创建管道
errcode = pipe(fds);
if (errcode < 0)
{
pr_debug("pipe() error");
return -1;
}
pr_debug("pipe() succeed,fds[0]:%d,fds[1]:%d",fds[0],fds[1]);
//创建接收连接线程
pthread_t dispatch_tid;
if (pthread_create(&dispatch_tid, NULL, dispatch_thread, (void*)NULL))
{
pr_debug("pthread_create() dispatch_thread error");
return -1;
}
pr_debug("pthread_create() dispatch_thread succeed");
max_fd = listen_fd;
addr_size=sizeof(sockaddr_in);
FD_ZERO(&all_set);
FD_SET(listen_fd, &all_set);
socket_maptable_t::iterator iter;
while(1)
{
read_set = all_set;
ready_size = select(max_fd+1, &read_set, NULL, NULL, NULL);
if ( FD_ISSET(listen_fd,&read_set) ) {
connect_fd = accept(listen_fd,(struct sockaddr *)&addr,&addr_size);
if (connect_fd ==-1 ) {
pr_debug("accept() error\n");
continue;
}
socket_maptable[connect_fd] = addr;
max_fd = connect_fd;
FD_SET(connect_fd, &all_set);
pr_debug("(%u) %s:%d connected,socket:%u",socket_maptable.size(),inet_ntoa(addr.sin_addr),ntohs(addr.sin_port),connect_fd);
}
for ( iter = socket_maptable.begin(); iter!=socket_maptable.end(); iter++)
{
sock_fd = iter->first;
addr = iter->second;
if ( FD_ISSET(sock_fd,&read_set) )
{
recv_size = recv(sock_fd, recv_buf, MAXDATASIZE,0);
bool bRet = (recv_size > 0);
bRet = bRet && process_client(sock_fd,addr,recv_buf,recv_size);
if ( !bRet)
{
close(sock_fd);
FD_CLR(sock_fd, &all_set);
socket_maptable.erase(sock_fd);
pr_debug("%s:%d disconnected\n",inet_ntoa(addr.sin_addr),ntohs(addr.sin_port) );
}
}
}
}
close(listen_fd);
}
bool process_client(int sockfd,sockaddr_in addr,char* recvbuf, int len)
{
int writed = write(fds[1],recvbuf,len);
pr_debug("datalen:%d,writed:%d",len,writed);
return (writed==len);
return true;
}