Windows Socket 学习

Posted langzou

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Windows Socket 学习相关的知识,希望对你有一定的参考价值。

Windows Socket 学习编程

最近需要调试socket程序,记录一下socket的demo。由于socket有多种情况,一下分开讨论。

阻塞式单Client模式

这种是最基本的模式,Server只等待一个Client连接,这种可用于两个进程或者线程之间的通信。

Server Code

void server(void* argc)
{
	WSADATA wd;
	WSAStartup(MAKEWORD(2, 2), &wd);

	/* 创建套接字 */
	SOCKET sktServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (sktServer == INVALID_SOCKET)
	{
		printf("socket server create fail
");
		return;
	}

	sockaddr_in addrSer = { 0 };
	addrSer.sin_family = AF_INET;		//服务器的IPV4协议
	addrSer.sin_port = htons(8080);		//服务器的端口
	addrSer.sin_addr.s_addr = inet_addr("127.0.0.1");//服务器的IP

	/* 绑定套接字*/
	int ret = bind(sktServer, (sockaddr*)&addrSer, sizeof(addrSer));
	if (ret == SOCKET_ERROR)
	{
		printf("socket server bind fail
");
		return;
	}

	/* 开始监听 */
	listen(sktServer, 1);

	/* 接收到client端连接 */
	SOCKET sktClient = accept(sktServer, NULL, NULL);

	/* 进入处理线程 */
	char buf[1024];
	while (true) {
		/* 接受客户端发送的数据 */
		printf("server recv start...
");
		recv(sktClient, buf, sizeof(buf), 0);
		printf("recv %s
", buf);

		/* 向客户端发送数据 */
		send(sktClient, buf, strlen(buf) + 1, 0);
	}

	WSACleanup();
}

阻塞式Client Code


void client(void* argc)
{
	WSADATA wd;
	WSAStartup(MAKEWORD(2, 2), &wd);

	/* 创建客户端套接字 */
	SOCKET sktClinet = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (sktClinet == INVALID_SOCKET)
	{
		printf("socket client create fail
");
		return;
	}

	sockaddr_in addrSer = { 0 };
	addrSer.sin_family = AF_INET;//要接的服务器的IPV4协议
	addrSer.sin_port = htons(8080);//要连接的服务器的端口
	addrSer.sin_addr.s_addr = inet_addr("127.0.0.1");//要连接的服务器的IP
	/* 连接本地服务器 */
	connect(sktClinet, (sockaddr*)&addrSer, sizeof(addrSer));

	const char* str = "hello world";
	char buf[1024] = { 0 };
	while (true) {
		send(sktClinet, str, strlen(str) + 1, 0);//向服务器发送数据
		recv(sktClinet, buf, sizeof(buf), 0);//接受服务器发送的数据
		printf("client recv %s
", buf);
		Sleep(1);
	}

	WSACleanup();
}

非阻塞式Client模式

Server端

void nonblocking_server(void* argc)
{
	WSADATA wd;
	WSAStartup(MAKEWORD(2, 2), &wd);

	SOCKET sktServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (sktServer == INVALID_SOCKET)
	{
		printf("socket server create fail
");
		return;
	}

	sockaddr_in addrSer = { 0 };
	addrSer.sin_family = AF_INET; //服务器的IPV4协议
	addrSer.sin_port = htons(8080);	//服务器的端口
	addrSer.sin_addr.s_addr = inet_addr("127.0.0.1");//服务器的IP

	/* 绑定套接字*/
	int ret = bind(sktServer, (sockaddr*)& addrSer, sizeof(addrSer));
	if (ret == SOCKET_ERROR)
	{
		printf("socket server bind fail
");
		return;
	}

	/* 开始监听 */
	listen(sktServer, 1);

	SOCKET sktClient = accept(sktServer, NULL, NULL);

	char buf[1024];
	int count = 0;
	while (true) {
		count++;
		sprintf(buf, "hello world count %d
", count);
		send(sktClient, buf, strlen(buf) + 1, 0);//向客户端发送数据
		Sleep(1); /* 延迟1s */
	}

	WSACleanup();
}

非阻塞Client端


void nonblocking_client(void* argc)
{
	int count = *(int*)argc;
	WSADATA wd;
	WSAStartup(MAKEWORD(2, 2), &wd);

	//创建客户端套接字
	SOCKET sktCli = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	unsigned long ul = 1;

	/* 非阻塞模式 */
	ioctlsocket(sktCli, FIONBIO, (unsigned long*)&ul);
	/* 阻塞超时模式 */
	int nNetTimeout = 500;//500ms,
	/* 设置发送超时 */
	//setsockopt(sktCli, SOL_SOCKET, SO_SNDTIMEO, (char*)&nNetTimeout, sizeof(int));
	/* 设置接收超时 */
	//setsockopt(sktCli, SOL_SOCKET, SO_RCVTIMEO, (char*)&nNetTimeout, sizeof(int));

	sockaddr_in addrSer = { 0 };
	addrSer.sin_family = AF_INET;//要接的服务器的IPV4协议
	addrSer.sin_port = htons(8080);//要连接的服务器的端口
	addrSer.sin_addr.s_addr = inet_addr("127.0.0.1");//要连接的服务器的IP
	//连接服务器
	connect(sktCli, (sockaddr*)& addrSer, sizeof(addrSer));

	char buf[1024];
	while (1) 
	{
		recv(sktCli, buf, sizeof(buf), 0);//接受服务器发送的数据
		printf("[server] %s
", buf);
	}

	WSACleanup();
}

多Client模式

服务器处理接收多个Client的模式

void mulitClient_server(void* argc)
{
	WSADATA wd;
	WSAStartup(MAKEWORD(2, 2), &wd);

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

	sockaddr_in addrSer = { 0 };
	addrSer.sin_family = AF_INET;		//服务器的IPV4协议
	addrSer.sin_port = htons(8080);		//服务器的端口
	addrSer.sin_addr.s_addr = inet_addr("127.0.0.1");//服务器的IP

	bind(skt, (sockaddr*)& addrSer, sizeof(addrSer));
	listen(skt, 5);

	char buf[1024];
	sockaddr_in addr = { 0 };
	int addrLen = sizeof(addr);
	while (true) {
		SOCKET sktCli = accept(skt, (sockaddr*)&addr, &addrLen);
		if (sktCli == INVALID_SOCKET) {
			printf("[client] accpet error ...
");
			return;
		}
		printf("[client] socket:%d ip:%s port:%d accept ...
", sktCli, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
		/* 单独创建处理线程 */
	}

	WSACleanup();

}

以上是关于Windows Socket 学习的主要内容,如果未能解决你的问题,请参考以下文章

Windows Socket 学习

Windows Socket网络编程学习笔记一

arm开发板上的linux如何通过网口和windows的网口通信,linux中的socket和windows下的socket能通用吗?

Windows 环境下的 Socket 编程 1 - 环境搭建和 Socket 相关函数

一个复杂的Windows下的socket程序

一个简单的Windows下的socket程序