zoukankan      html  css  js  c++  java
  • winsock select学习

    造了线程用select IO模型:

    #include <winsock.h>
    #include <stdio.h>
    
    #define PORT       5010
    #define MSGSIZE    1024
    
    #pragma comment(lib, "ws2_32.lib")
    
    int    g_iTotalConn = 0;
    SOCKET g_CliSocketArr[FD_SETSIZE];
    
    DWORD WINAPI WorkerThread(LPVOID lpParameter);
    
    int main()
    {
    	WSADATA     wsaData;
    	SOCKET      sListen, sClient;
    	SOCKADDR_IN local, client;
    	DWORD       dwThreadId;
    
    	// Initialize Windows socket library
    	WSAStartup(0x0202, &wsaData);
    
    	// Create listening socket
    	sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    
    	// Bind
    	local.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    	local.sin_family = AF_INET;
    	local.sin_port = htons(PORT);
    	bind(sListen, (struct sockaddr *)&local, sizeof(SOCKADDR_IN));
    
    	// Listen
    	listen(sListen, 3);
    
    	// Create worker thread
    	CreateThread(NULL, 0, WorkerThread, NULL, 0, &dwThreadId);
    
    	while (TRUE)
    	{
    		// Accept a connection
    		int iaddrSize = sizeof(client);
    		sClient = accept(sListen, (sockaddr*)&client, &iaddrSize);
    		printf("Accepted client:%s:%d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port));
    
    		// Add socket to g_CliSocketArr
    		g_CliSocketArr[g_iTotalConn++] = sClient;
    	}
    
    	return 0;
    }
    
    DWORD WINAPI WorkerThread(LPVOID lpParam)
    {
    	int i = 0;
    	fd_set fdread;
    	int ret = 0;
    	struct timeval tv = {1, 0};
    	char szMessage[MSGSIZE];
    
    	while (TRUE)
    	{
    		FD_ZERO(&fdread);
    		for (i = 0; i < g_iTotalConn; i++)
    		{
    			FD_SET(g_CliSocketArr[i], &fdread);//把所有的socket都塞到fd_set中
    		}
    
    		// We only care read event
    		ret = select(0, &fdread, NULL, NULL, &tv);//检测是否有数据可读
    
    		if (ret == 0)
    		{
    			// Time expired
    			continue;
    		}
    
    		for (i = 0; i < g_iTotalConn; i++)
    		{
    			if (FD_ISSET(g_CliSocketArr[i], &fdread))//对有数据可读的那个套接字  进行处理
    			{
    				// A read event happened on g_CliSocketArr
    				ret = recv(g_CliSocketArr[i], szMessage, MSGSIZE, 0);
    				if (ret == 0 || (ret == SOCKET_ERROR && WSAGetLastError() == WSAECONNRESET))
    				{//处理发生错误的时候
    					// Client socket closed
    					printf("Client socket %d closed.\n", g_CliSocketArr);
    					closesocket(g_CliSocketArr[i]);
    					if (i < g_iTotalConn - 1)
    					{            
    						g_CliSocketArr[i--] = g_CliSocketArr[--g_iTotalConn];
    					}
    				}
    				else
    				{//正常的情况
    					// We received a message from client
    					send(g_CliSocketArr[i], szMessage, ret, 0);
    				}
    			}
    		}
    
    	}//while
    
    	return 0;
    }
    

      客户端:

    #include<WinSock2.h>
    
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    #pragma comment(lib, "WS2_32")
    
    short gPort = 5010;
    const int MaxLine = 1024;
    
    
    void StrClient(SOCKET &aSockfd)
    {
    	string lStr;
    	while (getline(cin, lStr) != NULL)
    	{
    		send(aSockfd,lStr.c_str(),lStr.size(),0);
    
    		char lSendline[MaxLine];
    		int lReadSize = 0;
    		if ( (lReadSize = recv(aSockfd,lSendline,MaxLine,0) ) == 0 )
    		{
    			cerr << "sever terminated prematurely\n";
    			return ;
    		}
    		string lRecvStr(lSendline,lReadSize);
    		cout << lRecvStr << endl;
    	}
    }
    int main()
    {
    	int lRet = 0;
    	WSADATA lWsaData;
    	if ((lRet = WSAStartup(MAKEWORD(2,2), &lWsaData)) != 0)
    	{
    		cout << "Error " << lRet << endl;
    		return 0;
    	}
    	SOCKADDR_IN lAddr;
    	lAddr.sin_family = AF_INET;
    	lAddr.sin_port = htons(gPort);
    
    	int lNum = 0;
    	int lReadTime = 0;
    
    	SOCKET lSocket = socket(AF_INET, SOCK_STREAM, 0);
    	if (INVALID_SOCKET == lSocket)
    	{
    		cout << "INVALID_SOCKET" << endl;
    		return 0;
    	}
    
    	lAddr.sin_addr.s_addr = inet_addr("192.168.1.102");
    	if (connect(lSocket,(sockaddr*)(&lAddr),sizeof(lAddr)) < 0 )
    	{
    		cout << "connect error" << endl;
    		return 0;
    	}
    	StrClient(lSocket);
    
    	return 0;
    }
    

      

  • 相关阅读:
    文章评论:级数中达朗贝尔判别法和柯西判别法之间的关系研究 By 彭军
    解析函数论 Page 22 达朗贝尔判别法 VS 柯西判别法
    解析函數論 Page 28 連續復變函數的最簡單的性質
    #2066:一个人的旅行(Dijkstra算法入门题)
    #2072 单词数(字符串流使用)
    传统的DOM渲染方式 吴小明
    【闭包】closure 吴小明
    报文 吴小明
    节流和防抖 吴小明
    什么是模块化?它有什么好处?常用的模块化开发的方案 吴小明
  • 原文地址:https://www.cnblogs.com/xiangshancuizhu/p/2711393.html
Copyright © 2011-2022 走看看