码迷,mamicode.com
首页 > Windows程序 > 详细

Windows Socket 学习

时间:2020-12-07 12:40:02      阅读:13      评论:0      收藏:0      [点我收藏+]

标签:nec   接受   sprintf   time   线程之间的通信   sleep   end   window   bio   

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\n");
		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\n");
		return;
	}

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

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

	/* 进入处理线程 */
	char buf[1024];
	while (true) {
		/* 接受客户端发送的数据 */
		printf("server recv start...\n");
		recv(sktClient, buf, sizeof(buf), 0);
		printf("recv %s\n", 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\n");
		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\n", 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\n");
		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\n");
		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\n", 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\n", 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 ...\n");
			return;
		}
		printf("[client] socket:%d ip:%s port:%d accept ...\n", sktCli, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
		/* 单独创建处理线程 */
	}

	WSACleanup();

}

Windows Socket 学习

标签:nec   接受   sprintf   time   线程之间的通信   sleep   end   window   bio   

原文地址:https://www.cnblogs.com/langzou/p/14075108.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!