#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <errno.h>
#include <string.h>
#include <string>
#include <time.h>
#include <signal.h>
#include <pthread.h>
#include <sys/select.h>
#define THREAD_NUM 1024
static unsigned int recv_bytes[THREAD_NUM]={0};
static unsigned int thread_number=0;
static struct sigaction sa,sa_old;
struct thread_argument
{
int fd;
int number;
};
static bool to_listen=true;
void server(int fd,std::string host_ip,short host_port);
void signal_handler(int)
{
unsigned int bytes=0;
int i;
for(i=0;i<thread_number && thread_number<THREAD_NUM;++i)
{
bytes+=recv_bytes[i];
}
fprintf(stderr,"\nbytes=%u\n",bytes);
to_listen=false;
sigaction(SIGINT,&sa_old,NULL);
}
void * thread_routine(void *p)
{
int client_sockfd=(*(thread_argument *)p).fd;
int number=(*(thread_argument *)p).number;
const ssize_t RECV_SIZE=1024*32;
char data[RECV_SIZE]={0};
int ret;
while(1)
{
ret=read(client_sockfd, data,RECV_SIZE);
if(-1==ret)
{
if(EINTR==errno || EWOULDBLOCK==errno)
{
continue;
}
else
{
fprintf(stderr,"%s\n",strerror(errno));
break;
}
}
else if(0==ret)
{
fprintf(stderr,"thread %d recv over.\n",number+1);
break;
}
if(number<THREAD_NUM)
{
recv_bytes[number]+=ret;
}
else
{
fprintf(stderr,"warning: THREAD_NUM too samll\n");
}
}
close(client_sockfd);
delete (struct thread_argument *)p;
}
int main(int n,char *arg[])
{
sa.sa_handler=signal_handler;
sigaction(SIGINT,&sa,&sa_old);
if(3!=n)
{
fprintf(stderr,"usage ./server + host ip + port\n");
return -1;
}
std::string host_ip=std::string(arg[1]);
short host_port=static_cast<short>(atoi(arg[2]));
int server_sockfd;
server_sockfd=socket(AF_INET,SOCK_STREAM,0);
if(-1==server_sockfd)
{
fprintf(stderr,"%s\n",strerror(errno));
return -1;
}
server(server_sockfd,host_ip,host_port);
close(server_sockfd);
return 0;
}
void server(int fd,std::string host_ip,short host_port)
{
int reuse_addr=1;
if(-1==setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(const char*)&reuse_addr,sizeof(int)))
{
fprintf(stderr,"%s\n",strerror(errno));
return;
}
int recv_buf=32*1024;
if(-1==setsockopt(fd,SOL_SOCKET,SO_RCVBUF,(const char*)&recv_buf,sizeof(int)))
{
fprintf(stderr,"%s\n",strerror(errno));
return;
}
struct sockaddr_in server_addr;
server_addr.sin_family=AF_INET;
server_addr.sin_addr.s_addr=inet_addr(host_ip.c_str());
server_addr.sin_port=htons(host_port);
if(-1==bind(fd,(struct sockaddr *)&server_addr,sizeof(server_addr)))
{
fprintf(stderr,"%s\n",strerror(errno));
return;
}
if(-1==listen(fd,22))
{
fprintf(stderr,"%s\n",strerror(errno));
return;
}
int client_sockfd;
struct sockaddr_in client_addr;
socklen_t len=sizeof(client_addr);
fd_set read_set;
struct timeval timeout;
timeout.tv_sec=2;
timeout.tv_usec=0;
while(to_listen)
{
FD_ZERO(&read_set);
FD_SET(fd,&read_set);
if(-1==select(fd+1,&read_set,NULL,NULL,&timeout))
{
if(errno==EINTR)
{
continue;
}
else
{
fprintf(stderr,"%s\n",strerror(errno));
return;
}
}
if(!FD_ISSET(fd,&read_set))
{
continue;
}
client_sockfd=accept(fd,(struct sockaddr *)&client_addr,&len);
if(-1==client_sockfd)
{
fprintf(stderr,"%s\n",strerror(errno));
return;
}
struct thread_argument *p_arg=new struct thread_argument;
if(NULL==p_arg)
{
fprintf(stderr,"%s\n",strerror(errno));
return;
}
memset(p_arg,0,sizeof(struct thread_argument));
p_arg->fd=client_sockfd;
p_arg->number=thread_number;
pthread_t thread;
if(0!=pthread_create(&thread,NULL,thread_routine,p_arg))
{
fprintf(stderr,"%s\n",strerror(errno));
delete p_arg;
return;
}
if(0!=pthread_detach(thread))
{
fprintf(stderr,"%s\n",strerror(errno));
delete p_arg;
return;
}
thread_number++;
}//while
}
socket服务器端demo
最新推荐文章于 2022-06-23 19:44:44 发布