Liny_@NotePad

沉迷ACG中

【20090917】C++培训日记-网络编程基础

YOYO posted @ 2009年9月17日 22:56 in 【C/C++】 with tags Select 网络编程 , 2531 阅读

rt = = 今天的内容是基础的TCP\UDP Socket,以及TCP下使用Select。

【TCP】服务端

//////////////////////////////////////////////////////////////////////////
//	CopyRight(c) 2009, YOYO, All Rights Reserved.
//	Author: LIN YiQian
//	Created: 2009/09/17
//	Describe: TCP 服务端
//////////////////////////////////////////////////////////////////////////
#include <WinSock2.h>
#include <iostream>

#pragma comment(lib, "ws2_32.lib")

void main(void)
{
	WORD	wVersionRequired;
	WSADATA	wsaData;

	wVersionRequired = MAKEWORD(1, 1);		//	副版本号在前 主版本号在后

	int	nErr = WSAStartup(wVersionRequired, &wsaData);
	if (nErr != 0)
	{
		return;
	}

	if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)	//	版本错误
	{
		WSACleanup();
		return;
	}

	SOCKET	socketServer = socket(AF_INET, SOCK_STREAM, 0);

	SOCKADDR_IN	addrServer;
	addrServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY);	//	使用任意网卡上的IP地址
	addrServer.sin_port = htons(9989);		//	使用端口号
	addrServer.sin_family = AF_INET;

	bind(socketServer, (SOCKADDR*)&addrServer, sizeof(SOCKADDR));

	listen(socketServer, 5);

	SOCKET		socketClient;
	SOCKADDR_IN	addrClient;
	int	nLen = sizeof(SOCKADDR);

	while (true)
	{
		socketClient = accept(socketServer, (SOCKADDR*)&addrClient, &nLen);
		
		char szSendMsg[100];
		sprintf(szSendMsg, "Welcome %s to ND.\n", inet_ntoa(addrClient.sin_addr));
		send(socketClient, szSendMsg, strlen(szSendMsg) + 1, 0);

		char szRecvMsg[100];
		recv(socketClient, szRecvMsg, 100, 0);
		std::cout << szRecvMsg << std::endl;

		closesocket(socketClient);
	}

	closesocket(socketServer);

	WSACleanup();

	return;
}

【TCP】客户端

//////////////////////////////////////////////////////////////////////////
//	CopyRight(c) 2009, YOYO, All Rights Reserved.
//	Author: LIN YiQian
//	Created: 2009/09/17
//	Describe: TCP 客户端
//////////////////////////////////////////////////////////////////////////
#include <Winsock2.h>
#include <iostream>

#pragma comment(lib, "ws2_32.lib")

void main(void)
{
	WORD	wVersionRequired;
	WSADATA	wsaData;

	wVersionRequired = MAKEWORD(1, 1);

	int nErr = WSAStartup(wVersionRequired, &wsaData);
	if (nErr != 0)
	{
		return;
	}

	if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
	{
		WSACleanup();
		return;
	}

	SOCKET	socketClient = socket(AF_INET, SOCK_STREAM, 0);

	SOCKADDR_IN	addrServer;
	addrServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	addrServer.sin_port = htons(9989);
	addrServer.sin_family = AF_INET;

	connect(socketClient, (SOCKADDR*)&addrServer, sizeof(SOCKADDR));

	char szRecvMsg[100];
	recv(socketClient, szRecvMsg, 100, 0);
	std::cout << szRecvMsg << std::endl;

	char szSendMsg[100];
	sprintf(szSendMsg, "Re from Client..\n");
	send(socketClient, szSendMsg, strlen(szSendMsg) + 1, 0);

	closesocket(socketClient);

	WSACleanup();

	system("pause");

	return;
}

【UDP】服务端

//////////////////////////////////////////////////////////////////////////
//	CopyRight(c) 2009, YOYO, All Rights Reserved.
//	Author: LIN YiQian
//	Created: 2009/09/17
//	Describe: UDP 服务端
//////////////////////////////////////////////////////////////////////////
#include <WinSock2.h>
#include <iostream>

#pragma comment(lib, "ws2_32.lib")

void main(void)
{
	WORD	wVersionRequired;
	WSAData	wsaData;

	wVersionRequired = MAKEWORD(1, 1);

	int	nErr = WSAStartup(wVersionRequired, &wsaData);
	if (nErr != 0)
	{
		return;
	}
	
	if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
	{
		WSACleanup();
		return;
	}

	SOCKET	socketServer = socket(AF_INET, SOCK_DGRAM, 0);

	SOCKADDR_IN	addrServer;
	addrServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	addrServer.sin_port = htons(9989);
	addrServer.sin_family = AF_INET;

	bind(socketServer, (SOCKADDR*)&addrServer, sizeof(SOCKADDR));

	SOCKADDR_IN	addrClient;
	int	nLen = sizeof(SOCKADDR);

	while (true)
	{
		char szRecvMsg[100];
		recvfrom(socketServer, szRecvMsg, 100, 0, (SOCKADDR*)&addrClient, &nLen);
		std::cout << szRecvMsg << std::endl;
	}

	closesocket(socketServer);
	WSACleanup();

	system("pause");

	return;
}

【UDP】客户端

//////////////////////////////////////////////////////////////////////////
//	CopyRight(c) 2009, YOYO, All Rights Reserved.
//	Author: LIN YiQian
//	Created: 2009/09/17
//	Describe: UDP 客户端
//////////////////////////////////////////////////////////////////////////
#include <WinSock2.h>
#include <iostream>

#pragma comment(lib, "ws2_32.lib")

void main(void)
{
	WORD	wVersionRequired;
	WSADATA	wsaData;

	wVersionRequired = MAKEWORD(1, 1);

	int nErr = WSAStartup(wVersionRequired, &wsaData);
	if (nErr != 0)
	{
		return;
	}

	if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
	{
		WSACleanup();
		return;
	}

	SOCKET socketClient = socket(AF_INET, SOCK_DGRAM, 0);

	SOCKADDR_IN	addrServer;
	addrServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	addrServer.sin_port = htons(9989);
	addrServer.sin_family = AF_INET;

	char szSendMsg[100];
	sprintf(szSendMsg, "Connect Client!..\n");
	sendto(socketClient, szSendMsg, strlen(szSendMsg) + 1, 0, (SOCKADDR*)&addrServer, sizeof(SOCKADDR));

	closesocket(socketClient);

	WSACleanup();

	system("pause");

	return;
}

【TCP】使用Select-服务端

//////////////////////////////////////////////////////////////////////////
//	CopyRight(c) 2009, YOYO, All Rights Reserved.
//	Author: LIN YiQian
//	Created: 2009/09/17
//	Describe: TCP Select 服务端
//////////////////////////////////////////////////////////////////////////
#include <WinSock2.h>
#include <iostream>
#include <set>

#pragma comment(lib, "ws2_32.lib")

typedef std::set<SOCKET> SOCKET_SET;

void main(void)
{
	WSADATA	wsaData;

	if (WSAStartup( MAKEWORD(2, 2), &wsaData) != 0)
	{
		return;
	}

	if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
	{
		WSACleanup();
		return;
	}

	SOCKET	socketServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	SOCKADDR_IN	addrServer;
	addrServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	addrServer.sin_port = htons(9989);
	addrServer.sin_family = AF_INET;

	bind(socketServer, (SOCKADDR*)&addrServer, sizeof(SOCKADDR));
	
	listen(socketServer, 4);

	SOCKET			socketClient;
	struct fd_set	fdRead;
	int				nSize;
	SOCKET_SET		setSockets;

	char	szMsg[128];
	ZeroMemory(szMsg, sizeof(szMsg));

	int nBlockMilli = 0;
	struct timeval timeout;
	timeout.tv_sec = 0;
	timeout.tv_usec = 100;

	while (true)
	{
		FD_ZERO(&fdRead);		//	初始化fd_set
		FD_SET(socketServer, &fdRead);	//	分配套接字句柄到对应的fd_set

		select(FD_SETSIZE, &fdRead, NULL, NULL, &timeout);
		nSize = sizeof(addrServer);

		if (FD_ISSET(socketServer, &fdRead))	//	如果套接字句柄还在fd_set里,说明
												//	客户端已有connect的请求,马上就可以accept
		{
			socketClient = accept(socketServer, (SOCKADDR*)&addrServer, &nSize);
			setSockets.insert(socketClient);
		}

		FD_ZERO(&fdRead);
		for (SOCKET_SET::iterator iterSet = setSockets.begin(); iterSet != setSockets.end(); iterSet++)
		{
			FD_SET(*iterSet, &fdRead);
		}

		select(FD_SETSIZE, &fdRead, NULL, NULL, &timeout);
		for (SOCKET_SET::iterator iterSet = setSockets.begin(); iterSet != setSockets.end(); iterSet++)
		{
			if (FD_ISSET(*iterSet, &fdRead))
			{
				recv(*iterSet, szMsg, strlen(szMsg) + 1, 0);
				std::cout << szMsg << std::endl;
			}
		}
	}

	for (SOCKET_SET::iterator iterSet = setSockets.begin(); iterSet != setSockets.end(); iterSet++)
	{
		closesocket(*iterSet);
	}

	closesocket(socketServer);

	WSACleanup();

	return;
}

【TCP】使用Select-客户端

//////////////////////////////////////////////////////////////////////////
//	CopyRight(c) 2009, YOYO, All Rights Reserved.
//	Author: LIN YiQian
//	Created: 2009/09/17
//	Describe: TCP Select 客户端
//////////////////////////////////////////////////////////////////////////
#include <WinSock2.h>
#include <iostream>
#include <ctime>

#pragma comment(lib, "ws2_32.lib")

DWORD WINAPI ClientSocketThread(LPVOID lpParameter);

void main(void)
{
	WSADATA	wsaData;

	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
	{
		return;
	}

	if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
	{
		WSACleanup();
		return;
	}

	SYSTEM_INFO	systemInfo;
	GetSystemInfo(&systemInfo);

	//	开启CPU个数2倍的线程
	for (int i = 0; i < (systemInfo.dwNumberOfProcessors * 2); ++i)
	{
		HANDLE handle = CreateThread(NULL, 0, ClientSocketThread, NULL, 0, NULL);
		if (handle == NULL)
		{
			std::cout << "创建Client线程失败!" << std::endl;
		}
		CloseHandle(handle);
	}

	while (true)
	{
	}

	WSACleanup();

	return;
}

DWORD WINAPI ClientSocketThread(LPVOID lpParameter)
{
	SOCKET socketClient = socket(AF_INET, SOCK_STREAM, 0);

	SOCKADDR_IN	addrServer;
	addrServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	addrServer.sin_port = htons(9989);
	addrServer.sin_family = AF_INET;

	connect(socketClient, (SOCKADDR*)&addrServer, sizeof(SOCKADDR));

	char szMsg[100];
	srand(time(NULL));

	while (true)
	{
		sprintf(szMsg, "Socket %d connect..\n", socketClient);
		send(socketClient, szMsg, strlen(szMsg) + 1, 0);

		Sleep(100);
	}

	closesocket(socketClient);
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter