tcp server,包括端口复用,进程异常退出问题修复

有个朋友因为工作需要让我写一个tcpserver demo给他,于是有了下面这段代码,本程序包含了端口复用,进程异常退出问题的修复,希望对大家有所帮助!

 

 

#include<stdlib.h>
#include<stdio.h>
#include<sys/socket.h>
#include<netdb.h>
#include<string.h>
#include<unistd.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include <signal.h>

 
#define PORT 3301
#define HEARTBEATPORT 3302

//发送数据线程 
void *SendThreadpro(void *args)
{
    struct sockaddr_in server;
    struct sockaddr_in client;
    int len;
    int port;
    int listend;
    int connectd;
    int sendnum;
    int opt;
    int recvnum;
    char send_buf[2048];
    char recv_buf[2048];
 
 
    port= PORT;
    memset(send_buf,'\0',2048);
    memset(recv_buf,'\0',2048);
	
    opt = SO_REUSEADDR;
    if (-1==(listend=socket(AF_INET,SOCK_STREAM,0)))
    {
	 perror("create listen socket error\n");
	 pthread_exit(0);
	 return NULL;
    }
    setsockopt(listend,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));

    int  val = 1;    
    if (setsockopt(listend, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) == -1) 
    {		    
        pthread_exit(0);
        return NULL;
    }

    #if 0
    int reuse0 = 1;
    if (0 != setsockopt(listend, SOL_SOCKET, SO_REUSEPORT, (char *)&reuse0,         sizeof(reuse0))) 
    {        	   
    	pthread_exit(0);
    	return NULL;
    }
    #endif
 
 
    memset(&server,0,sizeof(struct sockaddr_in));
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = htonl(INADDR_ANY);
    server.sin_port = htons(port);
 
    if (-1==bind(listend,(struct sockaddr *)&server,sizeof(struct sockaddr)))
    {
	error("bind error\n");
        pthread_exit(0);
	return NULL;
    }
 
    if (-1==listen(listend, 20))
    {
	perror("listen error\n");
	pthread_exit(0);
	return NULL;
    }
	
    while (1)
    {
	if (0 > (connectd=accept(listend,(struct sockaddr*)&client,&len)))
    	{
	    perror("create connect socket error\n");
            continue;
    	}

	while (1)
	{
	    memset(send_buf,'\0',2048);
	    memset(recv_buf,'\0',2048);
	        
            if (0>(recvnum = recv(connectd,recv_buf,sizeof(recv_buf),0)))
    	    {
    			perror("recv error\n");
    			shutdown(connectd, 2);
    			close(connectd);
    			break;
    	    }
    	 
    	    printf ("the message from the client is: %s\n",recv_buf);	
    	    sprintf(send_buf, "hello nihao1 send packet");
    	  
    	    if (0 > send(connectd,send_buf,strlen(send_buf),0))
    	    {
                  perror("recv error\n");
    		  shutdown(connectd, 2);
    		  close(connectd);
    		  break;
    	    }
    		
    		usleep(5000);
	}
	   usleep(5000);
		
    }
	close(connectd);

        close(listend);

	pthread_exit(0);
}

//发送心跳函数
void *SendThreadHeartBeatpro(void *args)
{
	struct sockaddr_in server;
	struct sockaddr_in client;
	int len;
	int port;
	int listend;
	int connectd;
	int sendnum;
	int opt;
	int recvnum;
	char send_buf[2048];
	char recv_buf[2048];
 
 
	port= HEARTBEATPORT;
	memset(send_buf,'\0',2048);
	memset(recv_buf,'\0',2048);
	
    opt = SO_REUSEADDR;
	if (-1==(listend=socket(AF_INET,SOCK_STREAM,0)))
    {
	 perror("create listen socket error\n");
	 pthread_exit(0);
	 return NULL;
    }
    setsockopt(listend,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
 
    int  val = 1;    
	if (setsockopt(listend, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) == -1) 
	{		    
        	pthread_exit(0);
        	return NULL;
	}

    #if 0
    int reuse0 = 1;
	if (0 != setsockopt(listend, SOL_SOCKET, 15, (char *)&reuse0, sizeof(reuse0))) 
    {        	   
    	pthread_exit(0);
    	return NULL;
    }
    #endif
    
    memset(&server,0,sizeof(struct sockaddr_in));
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = htonl(INADDR_ANY);
    server.sin_port = htons(port);
 
    if (-1==bind(listend,(struct sockaddr *)&server,sizeof(struct sockaddr)))
    {
		error("bind error\n");
		pthread_exit(0);
		return NULL;
    }
 
    if (-1==listen(listend, 20))
    {
		perror("listen error\n");
		pthread_exit(0);
		return NULL;
    }
	
	while (1)
	{
		if (-1==(connectd=accept(listend,(struct sockaddr*)&client,&len)))
    	{
		    perror("create connect socket error\n");
		    continue;
    	}
	 
		while (1)
	    {
	        memset(send_buf,'\0',2048);
	        memset(recv_buf,'\0',2048);
	        
                if (0>(recvnum = recv(connectd,recv_buf,sizeof(recv_buf),0)))
    		{
    			perror("recv error\n");
    			close(connectd);
    			break;
    		}
    	 
    		printf ("the message from the client is: %s\n",recv_buf);	
    		sprintf(send_buf, "hello nihao2 HeartBeat");
    	  
    		if (0 > send(connectd,send_buf,strlen(send_buf),0))
    		{
                perror("recv error\n");
    			shutdown(connectd, 2);
    			close(connectd);
    			break;
    		}
    		
    		usleep(5000);
	    }
		
		usleep(5000);
	}
	close(connectd);

    close(listend);

	pthread_exit(0);
}
 
void SendThread()
{
	pthread_t mid1;
	if (pthread_create(&mid1, NULL, SendThreadpro,NULL))       //普通包
	{
		return;
	}
	
	pthread_detach(mid1);
}

void SendThreadHeartBeatThread()
{
	pthread_t mid2;
	if (pthread_create(&mid2, NULL, SendThreadHeartBeatpro,NULL))       //心跳
	{
		return;
	}
	
	pthread_detach(mid2);
}

//主进程
int main(int argc,char** argv)
{
  signal(SIGPIPE, SIG_IGN); //避免shutdown后进程退出
  signal(SIGCHLD,SIG_IGN);
	
  SendThread();
  SendThreadHeartBeatThread();

  printf("send data start!!!\n");
	
  while (1)
  {
    sleep(1);
  }

   return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值