• SDL_net TCP/UDP通信


    SDL_net TCP/UDP通信

    服务端:

    1. 初始化SDL_net库
    2. 设置监听的端口
    3. 打开一个socket绑定端口
    4. 接收连接
    5. 接受数据
    6. 对数据进行处理
    7. 清理,退出

    单线程服务器示例:

    #include <iostream>
    #include<Windows.h>
    #include<SDL.h>
    #include<SDL_net.h>
    
    #pragma comment(lib, "SDL2.lib")
    #pragma comment(lib, "SDL2main.lib")
    #pragma comment(lib, "SDL2_net.lib")
    using namespace std;
    
    int main(int argc, char* argv[])
    {
    	TCPsocket sd, csd; //定义服务端socket,和接收客户端socket
    	IPaddress ip, * remoteIP; //定义本机IP,客户端IP
    	bool quit = false;
    	char buffer[512] = { 0 };//接收数据缓存
    	//初始化SDL_net库
    	if (SDLNet_Init() < 0)
    	{
    		cout << "SDLNet_Init error:" << SDLNet_GetError() << endl;
    		return -1;
    	}
    	//解析主机和端口,nullptr为本机默认,端口15366
    	if (SDLNet_ResolveHost(&ip, nullptr, 15366)) {
    		cout << "SDLNet_ResolveHost error:" << SDLNet_GetError() << endl;
    		return -1;
    	}
    	//得到的变量ip地址和端口号值是大端模式
    
    	//打开一个TCP socket网络,监听主机的端口
    	if (!(sd = SDLNet_TCP_Open(&ip)))
    	{
    		cout << "SDLNet_TCP_Open error:" << SDLNet_GetError() << endl;
    		return -1;
    	}
    
    	//等待连接,发送数据
    	while (true)
    	{
    		//检查sd是否有新的连接,如果有,就接受,打开一个新的socket
    		if ((csd = SDLNet_TCP_Accept(sd)))
    		{
    			//获取远程地址
    			if ((remoteIP = SDLNet_TCP_GetPeerAddress(csd)))
    			{
    				//输出地址,和端口
    				cout << "Host connected:" << SDLNet_Read32(&remoteIP->host);
    				cout << "  " << SDLNet_Read16(&remoteIP->port) << endl;
    				char ip[32] = { 0 };
    				unsigned char* pch = (unsigned char*)&remoteIP->host;
    				sprintf_s(ip, "%d.%d.%d.%d", *pch, *(pch + 1), *(pch + 2), *(pch + 3));//将32位数字地址转为IP字符串形式
    				cout << ip << endl;
    				quit = false;
    				while (!quit)
    				{
    					int len = SDLNet_TCP_Recv(csd, buffer, 512);//这里是同步阻塞的
    					if (len > 0)//如果长度为0,则表示断开了连接
    					{
    						cout << buffer << endl;
    						if (strcmp(buffer, "exit") == 0)
    						{
    							quit = true;
    						}
    					}
    					else {
    						cout << "连接断开了" << endl;
    						break;
    					}
    					
    				}
    			}
    			else {
    				cout << "SDLNet_TCP_GetPeerAddress error:" << SDLNet_GetError() << endl;
    			}
    			::SDLNet_TCP_Close(csd);//关闭连接
    		}
    		else {
    			SDL_Delay(100);//延时一下,不然等待连接的过程中,CPU占用高
    		}
    	}
    	SDLNet_TCP_Close(sd);//关闭服务端socket
    	SDLNet_Quit();//清理SDL_net库
    	return 0;
    }
    
    
    

    简易的多线程处理示例:

    #include <iostream>
    #include<Windows.h>
    #include<SDL.h>
    #include<SDL_net.h>
    #include<thread>
    #pragma comment(lib, "SDL2.lib")
    #pragma comment(lib, "SDL2main.lib")
    #pragma comment(lib, "SDL2_net.lib")
    using namespace std;
    /// <summary>
    /// 处理客户端
    /// </summary>
    /// <param name="csd"></param>
    void dohandle(TCPsocket csd)
    {
    	IPaddress* remoteIP = nullptr;
    	string info = "";
    	//获取远程地址
    	if ((remoteIP = SDLNet_TCP_GetPeerAddress(csd)))
    	{
    		char ip[32] = { 0 };
    		unsigned char* pch = (unsigned char*)&remoteIP->host;
    		sprintf_s(ip, "%d.%d.%d.%d", *pch, *(pch + 1), *(pch + 2), *(pch + 3));//将32位数字地址转为IP字符串形式
    		info = string(ip) + ":" + to_string(remoteIP->port);
    		cout << "客户端:" << info << endl;
    		bool quit = false;
    		char buffer[512] = { 0 };
    		char send[512] = { 0 };
    		char serverN[] = "stdio回复:";
    		while (!quit)
    		{
    			memset(buffer, 0, sizeof(buffer));
    			int len = SDLNet_TCP_Recv(csd, buffer, sizeof(buffer));//这里是同步阻塞的
    			if (len > 0)//如果长度为0,则表示断开了连接
    			{
    				cout << "客户端(" << info << "):" << buffer << endl;
    				if (strcmp(buffer, "exit") == 0)//接收到字符"exit"则退出
    				{
    					quit = true;
    				}
    				else {
    					memset(send, 0, sizeof(send));
    					memcpy(send, serverN, sizeof(serverN));
    					strcat_s(send, buffer);
    					int l = SDLNet_TCP_Send(csd, send, strlen(send));//回复内容
    				}
    			}
    			else {//断开了
    				break;
    			}
    
    		}
    	}
    	else {
    		cout << "SDLNet_TCP_GetPeerAddress error:" << SDLNet_GetError() << endl;
    	}
    	cout << info << "断开了" << endl;
    	::SDLNet_TCP_Close(csd);//关闭连接
    }
    int main(int argc, char* argv[])
    {
    	TCPsocket sd, csd; //定义服务端socket,和接收客户端socket
    	IPaddress ip, * remoteIP; //定义本机IP,客户端IP
    	bool quit = false;
    	char buffer[512] = { 0 };//接收数据缓存
    	//初始化SDL_net库
    	if (SDLNet_Init() < 0)
    	{
    		cout << "SDLNet_Init error:" << SDLNet_GetError() << endl;
    		return -1;
    	}
    	//解析主机和端口,nullptr为本机默认,端口15366
    	if (SDLNet_ResolveHost(&ip, nullptr, 15366)) {
    		cout << "SDLNet_ResolveHost error:" << SDLNet_GetError() << endl;
    		return -1;
    	}
    	//得到的变量ip地址和端口号值是大端模式
    
    	//打开一个TCP socket网络,监听主机的端口
    	if (!(sd = SDLNet_TCP_Open(&ip)))
    	{
    		cout << "SDLNet_TCP_Open error:" << SDLNet_GetError() << endl;
    		return -1;
    	}
    
    	//等待连接,发送数据
    	while (true)
    	{
    		//检查sd是否有新的连接,如果有,就接受,打开一个新的socket
    		if ((csd = SDLNet_TCP_Accept(sd)))
    		{
    			thread th(dohandle, csd);
    			th.detach();
    		}
    		else {
    			SDL_Delay(100);//延时一下,不然等待连接的过程中,CPU占用高
    		}
    	}
    	SDLNet_TCP_Close(sd);//关闭服务端socket
    	SDLNet_Quit();//清理SDL_net库
    	return 0;
    }
    

    客户端:

    1. 初始化SDL_net库
    2. 解析服务器地址
    3. 打开一个socket
    4. 读取数据
    5. 发送数据
    6. 清理,退出

    简单示例:

    #include <iostream>
    #include<Windows.h>
    #include<SDL.h>
    #include<SDL_net.h>
    #include<thread>
    #pragma comment(lib, "SDL2.lib")
    #pragma comment(lib, "SDL2main.lib")
    #pragma comment(lib, "SDL2_net.lib")
    using namespace std;
    //接收数据处理线程
    void dohandler(TCPsocket sd)
    {
    	char buffer[512] = { 0 };
    	while (true)
    	{
    		memset(buffer, 0, 512);
    		int len = SDLNet_TCP_Recv(sd, buffer, 512);
    		if (len > 0)
    		{
    			cout << buffer << endl;
    		}
    		else
    		{
    			break;
    		}
    	}
    }
    int main(int argc, char* argv[])
    {
    	IPaddress ip;
    	TCPsocket sd;
    	int quit, len;
    	char buffer[512] = { "hello" };
    	if (SDLNet_Init() < 0)//初始化
    	{
    		cout << "SDLNet_Init:" << SDLNet_GetError() << endl;
    		return -1;
    	}
    	const char* dstip = "127.0.0.1";//目标IP地址,这里测试使用本地
    	if (SDLNet_ResolveHost(&ip, dstip, 15366) < 0)//目标服务器端口号15366
    	{
    		cout << "SDLNet_ResolveHost:" << SDLNet_GetError() << endl;
    		return -1;
    	}
    	if (!(sd = SDLNet_TCP_Open(&ip)))//打开连接
    	{
    		cout << "SDLNet_TCP_Open:" << SDLNet_GetError() << endl;
    		return -1;
    	}
    	thread th(dohandler, sd);//线程处理
    	th.detach();
    	quit = 0;
    	while (!quit)
    	{
    		len = strlen(buffer) + 1;
    		if (SDLNet_TCP_Send(sd, buffer, len) < len)//发送数据
    		{
    			cout << "SDLNet_TCP_Send:" << SDLNet_GetError() << endl;
    			return -1;
    		}
    		SDL_Delay(1000);//延时1秒
    	}
    	SDLNet_TCP_Close(sd);
    	SDLNet_Quit();
    	return 0;
    }
    

    UDP部分

    服务端:

    1. 初始化SDL_net库
    2. 在指定的端口打开一个socket
    3. 给数据包开辟内存
    4. 等待从客户端来的数据包
    5. 处理数据包
    6. 释放内存,退出

    服务端示例:

    #include <iostream>
    #include<Windows.h>
    #include<SDL.h>
    #include<SDL_net.h>
    #include<thread>
    #pragma comment(lib, "SDL2.lib")
    #pragma comment(lib, "SDL2main.lib")
    #pragma comment(lib, "SDL2_net.lib")
    using namespace std;
    
    int main(int argc, char* argv[])
    {
    	UDPsocket sd; //定义服务器socket
    	UDPpacket* p; //定义数据包
    	int quit;
    	//初始化SDL_net
    	if (SDLNet_Init() < 0)
    	{
    		cout << "SDLNet_Init:" << SDLNet_GetError() << endl;
    		return -1;
    	}
    	//打开一个socket端口15366
    	if (!(sd = SDLNet_UDP_Open(15366)))
    	{
    		cout << "SDLNet_UDP_Open:" << SDLNet_GetError() << endl;
    		return -1;
    	}
    	//给数据包开辟空间
    	if (!(p = SDLNet_AllocPacket(512)))
    	{
    		cout << "SDLNet_AllocPacket:" << SDLNet_GetError() << endl;
    		return -1;
    	}
    	quit = 0;
    	while (!quit)
    	{
    		if (SDLNet_UDP_Recv(sd, p))//接收数据
    		{
    			cout << "UDP Packet incoming" << endl;
    			cout << "Chan: " << p->channel << endl;
    			cout << "Data: " << p->data << endl;
    			cout << "Len: " << p->len << endl;
    			cout << "MaxLen: " << p->maxlen << endl;
    			cout << "Status: " << p->status << endl;
    			short port = SDLNet_Read16(&p->address.port);
    			unsigned char* ptr = (unsigned char*)&(p->address.host);
    			char buffer[20] = { 0 };
    			sprintf_s(buffer, "%d.%d.%d.%d", *ptr, *(ptr + 1), *(ptr + 2), *(ptr + 3));
    			cout << "Address:" << buffer << ":" << port << endl;
    			memset(p->data, 0, p->maxlen);//清空缓存区数据
    		}
    	}
    	SDLNet_UDP_Close(sd);
    	SDLNet_FreePacket(p);
    	SDLNet_Quit();
    	return 0;
    }
    

    客户端:

    1. 初始化SDL_net库
    2. 在一个随机的未使用的端口打开一个socket
    3. 解析服务器的地址
    4. 给数据包开辟内存
    5. 发送数据包
    6. 释放内存,退出

    客户端示例:

    #include <iostream>
    #include<Windows.h>
    #include<string>
    #include<SDL.h>
    #include<SDL_net.h>
    #include<thread>
    #pragma comment(lib, "SDL2.lib")
    #pragma comment(lib, "SDL2main.lib")
    #pragma comment(lib, "SDL2_net.lib")
    using namespace std;
    
    int main(int argc, char* argv[])
    {
    	UDPsocket sd;
    	IPaddress srvadd;
    	UDPpacket* p;
    	int quit;
    	if (SDLNet_Init() < 0)
    	{
    		cout << "SDLNet_Init:" << SDLNet_GetError() << endl;
    		return -1;
    	}
    	//打开一个随机的端口
    	if (!(sd = SDLNet_UDP_Open(0)))
    	{
    		cout << "SDLNet_UDP_Open:" << SDLNet_GetError() << endl;
    		return -1;
    	}
    	if (SDLNet_ResolveHost(&srvadd, "127.0.0.1", 15366))
    	{
    		cout << "SDLNet_ResolveHost:" << SDLNet_GetError() << endl;
    		return -1;
    	}
    	if (!(p = SDLNet_AllocPacket(512)))
    	{
    		cout << "SDLNet_AllocPacket:" << SDLNet_GetError() << endl;
    		return -1;
    	}
    	quit = 0;
    	while (!quit)
    	{
    		time_t tt = time(nullptr);
    		char buffer[100] = { "hello" };
    		SDL_strlcat(buffer, to_string(tt).c_str(), 100);
    		memcpy_s(p->data, 512, buffer, 100);
    		p->address.host = srvadd.host;//设置主机地址
    		p->address.port = srvadd.port; //主机端口
    		p->len = strlen((char*)p->data) + 1;
    		int len = SDLNet_UDP_Send(sd, -1, p);//发送数据
    		memset(p->data, 0, p->maxlen);
    		SDL_Delay(1000);
    	}
    	SDLNet_FreePacket(p);
    	SDLNet_Quit();
    	return 0;
    }
    
  • 相关阅读:
    python
    shader example
    shader 关键字
    Android Studio如何导出可供Unity使用的aar插件详解 转
    adb
    知识
    Unity实现模拟按键
    小知识
    图种制作命令
    八卦
  • 原文地址:https://www.cnblogs.com/zzr-stdio/p/14559965.html
Copyright © 2020-2023  润新知