zoukankan      html  css  js  c++  java
  • 30网络通信之多线程

    使用原始的Socket模式,会发生阻塞问题,只能收一条消息再发一条消息。无法做到发送多次消息。

    在服务器端创建多线程,每当accept()接受到一个客户端时,启动一条线程单独去处理。

     

    代码:

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<sys/socket.h>
    #include<netinet/in.h>
    #include<arpa/inet.h>
    #include<unistd.h>
    #include<pthread.h>
    
    #define SRV_PORT  0xabcd
    #define CLT_PORT  0xaaaa
    
    void *Comm_thread(void *param)
    {
    	int fd = *(int*)param;
    	int iRet;
    	char szBuf[1024];
    	char szMsg[] = "I Received!";
    
    	while(1)
    	{
    		memset(szBuf, 0, 1024);
    		iRet = read(fd, szBuf, 1024);
    		if (iRet < 0)
    		{
    			perror("Recv failed!");
    			break;
    		}
    		if (iRet == 0)
    		{
    			printf("Disconnect!
    ");
    			break;
    		}
    		else
    		{
    			printf("Recv:%s
    ", szBuf);
    			
    			//write(fd, szMsg, sizeof(szMsg));
    		}
    	}
    	close(fd);
    
    	return NULL;
    }
    
    
    void Tcp_server()
    {
    	int fd;
    	int iRet;
    	struct sockaddr_in  addr;
    	socklen_t addrlen = sizeof(addr);
    
    	fd = socket(PF_INET, SOCK_STREAM, 0);//IPPROTO_IP
    	if (fd < 0)
    	{
    		perror("Socket failed!");
    		return;
    	}
    	
    	addr.sin_family = AF_INET;//use IPV4 address
    	addr.sin_port   = htons(SRV_PORT);
    	addr.sin_addr.s_addr = htonl(INADDR_ANY);//INADDR_ANY=0L;
    	
    	iRet = bind(fd, (struct sockaddr*)&addr, addrlen);
    	if (iRet)
    	{
    		perror("Bind failed!");
    		close(fd);
    		return;
    	}
    
    	iRet = listen(fd, 10);
    	if (iRet)
    	{
    		perror("Listen failed!");
    		close(fd);
    		return;
    	}
    
    	int clientfd;
    	struct sockaddr_in srcaddr;
    	char szTip[] = "Welcome!";
    	//char szBuf[1024]={};
    
    	while(1)
    	{
    		clientfd = accept(fd,  (struct sockaddr*)&srcaddr, &addrlen);
    		if (clientfd < 0)
    		{
    			perror("Accept failed!");
    			break;
    		}
    
    		printf("Connect form %s[%d]
    ", inet_ntoa(srcaddr.sin_addr), ntohs(srcaddr.sin_port));
    
    		//send(clientfd, szTip, strlen(szTip), 0);
    		write(clientfd, szTip, strlen(szTip)); //send data to client
    
    		pthread_t  tid;
    		pthread_create(&tid, NULL, Comm_thread, (void*)&clientfd);
    	}
    
    	close(fd);
    
    	return ;
    
    }
    
    
    void Tcp_client()
    {
    	char szDestIp[16];
    	int  port;
    
    	fprintf(stderr, "Connect to:");
    	scanf("%s%d", szDestIp, &port);
    
    	int fd;
    	int iRet;
    	struct sockaddr_in srvaddr;
    	socklen_t addrlen = sizeof(srvaddr);
    
    	fd = socket(PF_INET, SOCK_STREAM, 0);
    	if (fd < 0)
    	{
    		perror("Socket failed!");
    		return;
    	}
    
    	srvaddr.sin_family = AF_INET;
    	srvaddr.sin_port  = htons((short)port);
    	srvaddr.sin_addr.s_addr = inet_addr(szDestIp);
    
    	iRet = connect(fd, (struct sockaddr*)&srvaddr, addrlen);
    	if (iRet)
    	{
    		perror("Connect failed!");
    		return;
    	}
    
    	char szBuf[1024];
    	char szMsg[100];
    	while(1)
    	{
    		memset(szBuf, 0, 1024);
    		iRet = read(fd, szBuf, 1024);//receive message
    		if (iRet < 0)
    		{
    			perror("Read failed!");
    			break;
    		}
    		if (iRet == 0)
    		{
    			printf("Server disconnected
    ");
    		}
    
    		printf("Recv: %s
    ", szBuf); 
    
    		fprintf(stderr, "Send:");
    		memset(szMsg, 0, 100);
    		read(STDIN_FILENO, szMsg, 100);//get message
    		
    		write(fd, szMsg, strlen(szMsg)); //send message
    
    	}
    
    }
    
    
    
    int main(int argc, char** argv)
    {
    	if (argc!=2 
    	   || (strcmp(argv[1], "s") && strcmp(argv[1], "c")  )
               )
    	{
    		printf("Usage: %s [ c | s ]
    ", argv[0]);
    		printf("	 c : For start tcp client
    ");
    		printf("	 s : For start tcp server
    ");	
    		return 0;
    	}
    	
    	if (argv[1][0] == 's')
    	{
    		Tcp_server();
    	}
    	else if (argv[1][0] == 'c')
    	{
    		Tcp_client();
    	}
    
    	return 0;
    }
    

      

  • 相关阅读:
    Django之 Choices参数、MVC和MTV模型、Ajax
    Django之聚合查询、分组查询、查询优化以及F、Q查询
    Django 之 模型层ORM操作
    Django关于视图层和模板层相关操作
    Django数据操作、ORM表设计、路由层
    Django三板斧,Django连接数据库
    前端--jQuery
    前端----BOM和DOM
    .zip.001 -- .zip.003解压缩
    HTTP Status Codes
  • 原文地址:https://www.cnblogs.com/gd-luojialin/p/10371572.html
Copyright © 2011-2022 走看看