服务端-并发

#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <time.h>
#include <sys/select.h>
#include <arpa/inet.h>
#include <signal.h>
#include <dirent.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <netinet/tcp.h>

#define PORT 28000 //端口号
#define BACKLOG 5	 //备份日志
#define MAXDATASIZE 1400 //最大数据大小
#define DEBUG 1	 //定义DEBUG
#define ONTIME 60	 //准时
#define NAMELEN 40	 //名字长度

pthread_mutex_t mutex;	 //线程锁头
pthread_mutex_t guard_gdata; //

int threadcount=20000; //default htread count 总共的线程数量

char sFilePath[40] = "/home/weizhou/cash/";//设置路径
int iFileIndex = 1;//文件节点 
typedef struct ARG{
int connfd;
unsigned int thread_handle;
struct sockaddr_in client;
}ARG;//设置传递参数的类型

void *rtx;//设置一个指针

void* start_routine(void* arg);
void process_cli(int connectfd, struct sockaddr_in client);

int listenfd;

int mypid=0;

int count=0;

void signal_hander(int x);

void signal_hander(int x) 
{ 
// printf("i am here\n");
close(listenfd);
exit(1);
}

int main(int agrc,char *argv[])
{

system("echo 300 > /proc/sys/net/ipv4/tcp_keepalive_time");
system("echo 60 > /proc/sys/net/ipv4/tcp_keepalive_intvl");
system("echo 10 > /proc/sys/net/ipv4/tcp_keepalive_probes");
//system("echo 10 > /proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_timeout_time_wait");
//system("echo 1200 > /proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_timeout_established");


pthread_mutex_init(&mutex, NULL); 
pthread_mutex_init (&guard_gdata, NULL);

int i;

struct ARG arg1[threadcount]; //default threadcount=10000
for(i=0;i<threadcount;i++)
{
arg1[i].connfd=0; 
arg1[i].thread_handle=0; 
}

int connectfd;
pthread_t thread; //id of thread
ARG *arg; //pass this var to the thread
struct sockaddr_in server; //server's address info
struct sockaddr_in client; //client's
int sin_size;

//create tcp socket
if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
perror("creating socket failed.");
exit(1);
}

int opt = SO_REUSEADDR;
setsockopt(listenfd, SOL_SOCKET,SO_REUSEADDR, &opt, sizeof(opt));

bzero(&server,sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
server.sin_addr.s_addr = htonl(INADDR_ANY);

if(bind(listenfd,(struct sockaddr *)&server,sizeof(struct sockaddr)) == -1) {

exit(1);

}
if(listen(listenfd,BACKLOG) == -1) {

exit(1);

}

sin_size = sizeof(struct sockaddr_in);

signal(SIGKILL|SIGTERM,signal_hander);

mypid=getpid();

while(1)
{

if((connectfd = accept(listenfd, (struct sockaddr *)&client, (socklen_t*)&sin_size)) == -1) {

for(i=0;i<threadcount;i++)
{
if (arg1[i].thread_handle>0 && arg1[i].connfd==0)
{
pthread_join(arg1[i].thread_handle,&rtx);
arg1[i].thread_handle=0; 
}

}
close(connectfd);
continue; 
}

for(i=0;i<threadcount;i++)
{
if (arg1[i].connfd==0 && arg1[i].thread_handle==0) break;

}

if (i==threadcount)
{
for(i=0;i<threadcount;i++)
{
if (arg1[i].thread_handle>0 && arg1[i].connfd==0)
{
pthread_join(arg1[i].thread_handle,&rtx);
arg1[i].thread_handle=0;
}

}
close(connectfd);
continue;
}

arg1[i].connfd = connectfd;
memcpy((void *)&arg1[i].client, &client, sizeof(client));
arg=&arg1[i];

if (( pthread_create(&thread, NULL, start_routine, (void*)arg)) !=0){


for(i=0;i<threadcount;i++)
{
if (arg1[i].thread_handle>0 && arg1[i].connfd==0)
{
//pthread_cancel(arg1[i].thread_handle);
pthread_join(arg1[i].thread_handle,&rtx);
arg1[i].thread_handle=0;
}

}

close(connectfd);
continue;

}

if (thread>0)
{ 
arg1[i].thread_handle=thread;
}


for(i=0;i<threadcount;i++)
{
if (arg1[i].thread_handle>0 && arg1[i].connfd==0)
{

pthread_join(arg1[i].thread_handle,&rtx);
arg1[i].thread_handle=0; 
} 
}
}

close(listenfd);

return 0;

}


void* start_routine(void* arg)
{

ARG *info;
info=(ARG*)arg;
process_cli(info->connfd,info->client);
close(info->connfd);
info->connfd=0;
pthread_exit(NULL); 
return NULL;

}


//handle the request of the client

void process_cli(int connectfd, struct sockaddr_in client)
{

//yourself bussness rules;
FILE * RcvFile;
char RcvFileName[40];
int iRcvNum;
char cRcvBuffer[MAXDATASIZE];

struct timeval timeout={40,0};
setsockopt(connectfd,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout,sizeof(struct timeval));
setsockopt(connectfd,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(struct timeval)); 
pthread_mutex_lock (&guard_gdata);
sprintf (RcvFileName, "%sdemo%d.txt",sFilePath ,iFileIndex++);	
if ((RcvFile = fopen (RcvFileName, "wb+")) == NULL)
{
printf ("fail to open %s.\n", RcvFileName);
printf ("%s\n", strerror(errno));
return ;
}
pthread_mutex_unlock (&guard_gdata);

while(1)
{
if ((iRcvNum =recv(connectfd, cRcvBuffer, MAXDATASIZE, 0)) == -1)
{
printf ("recv error.\n");
return ;
}

if (iRcvNum == 0)
break;
iRcvNum = fwrite (cRcvBuffer, iRcvNum, 1, RcvFile);
printf ("write %d bytes data to %s.\n", iRcvNum, RcvFile);
//yourself bussness rules; 
}
if (fclose(RcvFile) != 0)
printf ("file closed fail.\n");
return;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值