• 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;
    }
    

      

  • 相关阅读:
    保持URL不变和数字验证
    centOS ftp key?
    本地环境测试二级域名
    linux 解决You don't have permission to access 问题
    php smarty section loop
    php header Cannot modify header information headers already sent by ... 解决办法
    linux部分命令
    Linux 里面的文件操作权限说明
    用IT网络和安全专业人士视角来裁剪云的定义
    SQL Server 2008 R2炫酷报表"智"作有方
  • 原文地址:https://www.cnblogs.com/gd-luojialin/p/10371572.html
Copyright © 2020-2023  润新知