winsock select 模型 很幽默的讲解六种Socket I/O模型

// 客户端代码
#include <STDIO.H>
#include <WINSOCK2.H>
#pragma comment(lib,"Ws2_32.lib")

#define SERVER_ADDRESS "192.168.1.150"
#define PORT 5150
#define MSGSIZE 1024

int main(int argc, char* argv[])
{
	WORD wVersionRequested;
	WSADATA wsaData;

	// Initialize windows socket library
	wVersionRequested = MAKEWORD( 2, 2 );
	WSAStartup(wVersionRequested,&wsaData);

	// Create client socket
	SOCKET sClient;
	sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	
	//
	SOCKADDR_IN server;
	//memset(&server, 0, sizeof(SOCKADDR_IN));
	server.sin_family = AF_INET;
	server.sin_addr.S_un.S_addr = inet_addr(SERVER_ADDRESS);
	server.sin_port = htons(PORT);

	connect(sClient, (SOCKADDR*)&server, sizeof(SOCKADDR));

	char msgbuffer[MSGSIZE];
	int ret;

	while(true)
	{
		printf("Send:");
		gets(msgbuffer);

		// send message
		send(sClient, msgbuffer, MSGSIZE, 0);

		// receive message
		ret = recv(sClient,msgbuffer,MSGSIZE,0);
		msgbuffer[ret] = '\0';
		printf("Received [%d bytes]: %s '\n'",ret, msgbuffer);
	}
	closesocket(sClient);
	WSACleanup();

	return 0;
}

// 服务器端
#include <STDIO.H>
#include <WINSOCK2.H>
#pragma  comment(lib,"Ws2_32.lib")

#define PORT 5150
#define MSGSIZE 1024

int g_clientCount = 0;
SOCKET g_clientSocketArray[FD_SETSIZE];

DWORD WINAPI WorkerThread(LPVOID lpParameter)   // thread data						  
{
	int i;
	fd_set fdread;
	int ret;

	TIMEVAL tv = {1,0};

	char msg[MSGSIZE];

	while(true)
	{
		FD_ZERO(&fdread);

		for(i=0; i < g_clientCount; i++)
		{
			FD_SET(g_clientSocketArray[i], &fdread);
		}

		ret = select(0, &fdread, NULL, NULL, &tv);
		if(ret == 0)
		{
			continue;
		}

		for(i=0; i<g_clientCount;i++)
		{
			if(FD_ISSET(g_clientSocketArray[i], &fdread))
			{
				ret = recv(g_clientSocketArray[i], msg, MSGSIZE, 0);

				if (ret == 0 || (ret == SOCKET_ERROR && WSAGetLastError() == WSAECONNRESET))   
				{
					// client socket closed
					printf("client socket %d closed. \n",g_clientSocketArray[i]);
					closesocket(g_clientSocketArray[i]);

					if(i<g_clientCount - 1)
					{
						//g_clientSocketArray[i--] = g_clientSocketArray[--g_clientCount];
						g_clientSocketArray[i] = g_clientSocketArray[g_clientCount];
						i--;
						g_clientCount--;
					}
				}
				else
				{
					msg[ret] = '\0';
					send(g_clientSocketArray[i], msg, strlen(msg), 0);
				}
			}
		}

	}


	return 0;
}


int main(int argc, char* argv[])
{
	WORD wVersionRequested;
	WSADATA wsaData;
	
	wVersionRequested = MAKEWORD(2,2);
	WSAStartup(wVersionRequested,&wsaData);
	
	// listen socket
	SOCKET sListen;
	sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	
	// bind
	SOCKADDR_IN local;
	local.sin_family = AF_INET;
	local.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	local.sin_port = htons(PORT);
	bind(sListen, (SOCKADDR*)&local, sizeof(SOCKADDR));
	
	// listen
	listen(sListen, 3);
	
	// thread
	DWORD threadID;
	CreateThread(NULL, 0, WorkerThread, NULL, 0, &threadID);
	
	// accept
	SOCKET sClient;
	SOCKADDR_IN client;
	int len = sizeof(SOCKADDR);

	

	while(true)
	{
		// 
		sClient = accept(sListen, (SOCKADDR*)&client, &len);
		
		printf("Accept client: %s:%d\n",inet_ntoa(client.sin_addr),ntohs(client.sin_port));
		
		g_clientSocketArray[g_clientCount++] = sClient;
		
	}

	return 0;
}


你可能感兴趣的:(winsock select 模型 很幽默的讲解六种Socket I/O模型)