zoukankan      html  css  js  c++  java
  • 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();
    
    }
    
  • 相关阅读:
    PS转换图片——我教你
    通过Ajax——异步获取相关问题解答
    Spring的线程安全
    Spring MVC的工作机制
    Annotation的语法和使用
    Spring Bean的生命周期
    浅谈Spring
    Spring的事务管理
    行为型模式
    结构型模式
  • 原文地址:https://www.cnblogs.com/langzou/p/14075108.html
Copyright © 2011-2022 走看看