当前位置: 首页 > 工具软件 > usocket > 使用案例 >

USocket UE4TCP UDP接口

酆恩
2023-12-01

  
  
// USocket.cpp : 定义控制台应用程序的入口点。 // //#define printf_s printf
#include "stdafx.h" #include "USocket.h"
#include <stdio.h> #include <list>
OnReceive* OnTCPReceive; OnServerAccept* OnServeAccept; OnReceiveForm* OnServerReceive; OnReceiveForm* OnUDPReceive;
void UDPReceiveThread(SOCKET* udpclient); void TCPReceiveThread(SOCKET* client);
void ServerReceiveThread(PeerSocket* peer); void ServerAcceptThread(SOCKET* server);
std::list<SOCKET*>* tcpclients; std::list<SOCKET*>* udpclients; std::list<SOCKET*>* tcpservers;
WSADATA wsaData;
void Init() {  tcpclients = new std::list<SOCKET*>();  udpclients = new std::list<SOCKET*>();  tcpservers = new std::list<SOCKET*>();  int result = WSAStartup(MAKEWORD(2, 2), &wsaData);  if (result)printf_s("Init error:%d\n", WSAGetLastError()); }
FILE* consolefile; void OpenConsole() {  AllocConsole();  freopen_s(&consolefile, "CONOUT$", "w+t", stdout);  //consolefile = freopen("CONOUT$", "w+t", stdout); }
void CloseConsole() {  fclose(consolefile);  FreeConsole(); }
void Shutdown() {  WSACleanup(); }
SOCKET* CreateTCPClient(unsigned short port) {  SOCKET* sockClient = new SOCKET();  *sockClient = socket(AF_INET, SOCK_STREAM, 0);
 int result = 0;  sockaddr_in addrClient;  int addrlen = sizeof(sockaddr);  if (port)  {//绑定自定义端口   addrClient.sin_family = AF_INET;   addrClient.sin_addr.s_addr = inet_addr("127.0.0.1");   addrClient.sin_port = htons(port);   result |= bind(*sockClient, (SOCKADDR*)&addrClient, sizeof(addrClient));   if (result)printf_s("CreateTCPClient error:%d\n", WSAGetLastError());
  result |= getsockname(*sockClient, (sockaddr*)&addrClient, &addrlen);   if (result)printf_s("CreateTCPClient error:%d\n", WSAGetLastError());   printf_s("TCP指定端口:%s:%d\n", inet_ntoa(addrClient.sin_addr), ntohs(addrClient.sin_port));  }  else  {   printf_s("TCP端口未指定\n");  }
 tcpclients->push_back(sockClient);  return sockClient; }
SOCKET* CreateTCPServer(unsigned short port) {  SOCKET* sockServer = new SOCKET();  *sockServer = socket(AF_INET, SOCK_STREAM, 0);
 int result = 0;  sockaddr_in addrServer;  int addrlen = sizeof(sockaddr);  if (port)  {//绑定自定义端口   addrServer.sin_family = AF_INET;   addrServer.sin_addr.s_addr = inet_addr("127.0.0.1");   addrServer.sin_port = htons(port);   result |= bind(*sockServer, (SOCKADDR*)&addrServer, sizeof(addrServer));   if (result)printf_s("CreateTCPServer error:%d\n", WSAGetLastError());
  result |= getsockname(*sockServer, (sockaddr*)&addrServer, &addrlen);   if (result)printf_s("CreateTCPServer error:%d\n", WSAGetLastError());   printf_s("指定端口:%s:%d\n", inet_ntoa(addrServer.sin_addr), ntohs(addrServer.sin_port));  }  else  {   printf_s("服务端未分配端口\n");  }
 tcpservers->push_back(sockServer);  return sockServer; }
void ServerListenAccept(SOCKET* server, int maxconn) {  int i = 0;  int result = listen(*server, maxconn);  if (result)printf_s("ServerListenAccept error:%d\n", WSAGetLastError());
 sockaddr_in addrClient;  int addrlen;  do  {   SOCKET client = accept(*server, 0, 0);   if (client == INVALID_SOCKET)   {    printf_s("无效socket, error:%d\n", WSAGetLastError());    continue;   }   result |= getsockname(client, (sockaddr*)&addrClient, &addrlen);   if (result)printf_s("ServerListenAccept error:%d\n", WSAGetLastError());   printf_s("连接客户端:%s:%d\n", inet_ntoa(addrClient.sin_addr), ntohs(addrClient.sin_port));   i += 1;  } while (i < maxconn);  printf_s("连接客户端数已经最大"); }
void ServerListenAcceptAsync(SOCKET* server, int maxconn) {  int result = 0;  result = listen(*server, maxconn);  if (result)printf_s("ServerListenAcceptAsync error:%d\n", WSAGetLastError());
 DWORD threadID;  HANDLE hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)ServerAcceptThread, server, 0, &threadID);  printf_s("接受线程:%d, Thread ID:%d\n", hThread, threadID); }
SOCKET* CreateUDPClient(unsigned short port) {  SOCKET* sockClient = new SOCKET();  *sockClient = socket(AF_INET, SOCK_DGRAM, 0);
 int result = 0;  sockaddr_in addrClient;  int addrlen = sizeof(sockaddr);  if (port)  {//绑定自定义端口   addrClient.sin_family = AF_INET;   addrClient.sin_addr.s_addr = inet_addr("127.0.0.1");   addrClient.sin_port = htons(port);   result |= bind(*sockClient, (SOCKADDR*)&addrClient, sizeof(addrClient));   if (result)printf_s("CreateUDPClient error:%d\n", WSAGetLastError());
  result |= getsockname(*sockClient, (sockaddr*)&addrClient, &addrlen);   if (result)printf_s("CreateUDPClient error:%d\n", WSAGetLastError());   printf_s("UDP指定端口:%s:%d\n", inet_ntoa(addrClient.sin_addr), ntohs(addrClient.sin_port));  }  else  {   getsockname(*sockClient, (sockaddr*)&addrClient, &addrlen);   printf_s("TCP端口未指定\n");  }
 udpclients->push_back(sockClient);  return sockClient; }
int SocketIONonBlocking(SOCKET* s, int mode) {  u_long iMode = mode;  int result = ioctlsocket(*s, FIONBIO, &iMode);  if (result)printf_s("error:%d\n", WSAGetLastError());  return result; }
int TCPConnectToServer(SOCKET* sockClient, char* IP, unsigned short port) {  printf_s("参数 %s:%d\n", IP, port);  int result = 0;  SOCKADDR_IN addrServer;  addrServer.sin_addr.S_un.S_addr = inet_addr(IP);  addrServer.sin_family = AF_INET;  addrServer.sin_port = htons(port);  result |= connect(*sockClient, (SOCKADDR*)&addrServer, sizeof(SOCKADDR));  if (result)printf_s("TCPConnectToServer error:%d\n", WSAGetLastError());
 sockaddr_in addrClient;  int addrlen = sizeof(sockaddr);  result |= getsockname(*sockClient, (sockaddr*)&addrClient, &addrlen);  if (result)printf_s("TCPConnectToServer error:%d\n", WSAGetLastError());  printf_s("TCP连接端口:%s:%d\n", inet_ntoa(addrClient.sin_addr), ntohs(addrClient.sin_port));  return result;//一直为0代表无错误 }
void SetTCPReceiveCallBack(OnReceive* func) {  OnTCPReceive = func; }
void SetUDPReceiveCallBack(OnReceiveForm* func) {  OnUDPReceive = func; }
void SetServerAcceptCallBack(OnServerAccept* func) {  OnServeAccept = func; }
void SetServerReceiveCallBack(OnReceiveForm* func) {  OnServerReceive = func; }
void UDPReadAsyncLoop(SOCKET* s) {  DWORD threadID;  HANDLE hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)UDPReceiveThread, s, 0, &threadID);  printf_s("UDP接收线程:%d, Thread ID:%d\n", hThread, threadID); }
void TCPReadAsyncLoop(SOCKET* s) {  DWORD threadID;  HANDLE hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)TCPReceiveThread, s, 0, &threadID);  printf_s("TCP接收线程:%d, Thread ID:%d\n", hThread, threadID); }
void ServerReadAsyncLoop(PeerSocket* peer) {  DWORD threadID;  HANDLE hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)ServerReceiveThread, peer, 0, &threadID);  printf_s("Server接收线程:%d, Thread ID:%d\n", hThread, threadID); }
SOCKET* IsTCPClient(SOCKET* s) {  for (std::list<SOCKET*>::iterator itr = tcpclients->begin(); itr != tcpclients->end(); itr++)   if (*itr == s)    return s;  return NULL; }
SOCKET* IsUDPClient(SOCKET* s) {  for (std::list<SOCKET*>::iterator itr = udpclients->begin(); itr != udpclients->end(); itr++)   if (*itr == s)    return s;  return NULL; }
SOCKET* IsTCPServer(SOCKET* s) {  for (std::list<SOCKET*>::iterator itr = tcpservers->begin(); itr != tcpservers->end(); itr++)   if (*itr == s)    return s;  return NULL; }
int TCPReceive(SOCKET* client, char* data,int* datasize) {  int result = 0;  if (IsTCPClient(client))  {   int len = recv(*client, data, *datasize, 0);//非阻塞模式,不取return的值   *datasize = len;   result = WSAGetLastError();  }  else   printf_s("It's not USocket TCPClient\n");  return result; }
int UDPReceive(SOCKET* client, char* data, int* datasize, char* outfrom, int* port) {  int result = 0;  sockaddr_in SenderAddr;  int addrlen = sizeof(sockaddr);  if (IsUDPClient(client))  {   int len = recvfrom(*client, data, *datasize, 0, (sockaddr*)&SenderAddr, &addrlen);   *datasize = len;   result = WSAGetLastError();   outfrom = inet_ntoa(SenderAddr.sin_addr);   *port = ntohs(SenderAddr.sin_port);  }  else   printf_s("It's not USocket TCPClient\n");  return 0; }
int ServerReceive(PeerSocket* peer, char* data, int* datasize) {  int result = 0;  if (IsTCPServer(peer->server))  {   int len = recv(*peer->tcp, data, *datasize, 0);   *datasize = len;   result = WSAGetLastError();  }  else   printf_s("It's not USocket TCPClient\n");  return 0; }
int TCPSendToServer(SOCKET* client, char* data, int len) {  int result = 0;  if (IsTCPClient(client))  {   result = send(*client, data, len, 0);   if (result)printf_s("TCPSendToServer error:%d\n", WSAGetLastError());  }  else   printf_s("It's not USocket TCPClient\n");  return result; }
int ServerSend(PeerSocket* peer, char* data, int len) {  int result = 0;  if (IsTCPServer(peer->server))  {   result = send(*peer->tcp, data, len, 0);   if (result)printf_s("ServerSend error:%d\n", WSAGetLastError());  }  else   printf_s("It's not USocket TCPServer\n");  return result; }
int UDPSendTo(SOCKET* client, char* data, int len, char* IP, int port) {  int result = 0;  if (IsUDPClient(client))  {   sockaddr_in RecvAddr;   RecvAddr.sin_family = AF_INET;   RecvAddr.sin_addr.s_addr = inet_addr(IP);   RecvAddr.sin_port = htons(port);   result = sendto(*client, data, len, 0, (SOCKADDR*)&RecvAddr, sizeof(RecvAddr));   if (result)printf_s("UDPSendTo error:%d\n", WSAGetLastError());  }  else   printf_s("It's not USocket UDPClient\n");  return result; }
int Close(SOCKET* s) {  if (IsUDPClient(s))   udpclients->remove(s);  else if (IsTCPClient(s))   tcpclients->remove(s);  else if (IsTCPServer(s))   tcpservers->remove(s);  int result = closesocket(*s);  if (result)printf_s("error:%d\n", WSAGetLastError());  return result; }
void UDPReceiveThread(SOCKET* socket) {  char data[4096];  do  {   sockaddr_in SenderAddr;   int addrlen = sizeof(sockaddr);   memset(data, 0, 4096);   int len = recvfrom(*socket, data, 4096, 0, (sockaddr*)&SenderAddr, &addrlen);   //阻塞模式 len是字节数量   //非阻塞模式 len是WSAEWOULDBLOCK(10035)   int err = WSAGetLastError();   if (err)return;   if (len <= 0)return;   char IPAddr[22];   sprintf_s(IPAddr, "%s:%d", inet_ntoa(SenderAddr.sin_addr), ntohs(SenderAddr.sin_port));   if (OnUDPReceive)   {    OnUDPReceive(socket, data, len, IPAddr, strnlen_s(IPAddr, 22));   }   else   {//    printf_s("UDP接收未设定回调函数,*data:%p\n", data);   }  } while (true); }
void TCPReceiveThread(SOCKET* socket) {  char data[4096];  do  {   memset(data, 0, 4096);   int len = recv(*socket, data, 4096, 0);   int err = WSAGetLastError();   if (err)return;   if (len <= 0)return;   if (OnTCPReceive)   {    OnTCPReceive(socket, data, len);   }   else   {//    printf_s("TCP接收未设定回调函数,*data:%p\n", data);   }  } while (true); }
void ServerAcceptThread(SOCKET* server) {  do  {   sockaddr_in addrClient;   int addrlen = sizeof(sockaddr);   SOCKET* client = new SOCKET();   *client = accept(*server, 0, 0);   getpeername(*client, (sockaddr*)&addrClient, &addrlen);   printf_s("接入客户端:%s:%d\n", inet_ntoa(addrClient.sin_addr), ntohs(addrClient.sin_port));   if (OnServeAccept)    OnServeAccept(server, client);  } while (true); }
void ServerReceiveThread(PeerSocket* peer) {  char data[4096];  do  {   sockaddr_in SenderAddr;   int addrlen = sizeof(sockaddr);      memset(data, 0, 4096);   int len = recv(*peer->tcp, data, 4096, 0);   int err = WSAGetLastError();   if (err)return;   if (len <= 0)return;   char IPAddr[22];   getpeername(*peer->tcp, (sockaddr*)&SenderAddr, &addrlen);   sprintf_s(IPAddr, "%s:%d", inet_ntoa(SenderAddr.sin_addr), ntohs(SenderAddr.sin_port));   if (OnServerReceive)   {    OnServerReceive(peer->server, data, len, IPAddr, strnlen_s(IPAddr, 22));   }   else   {//    printf_s("Server接收未设定回调函数,*data:%p\n", data);   }  } while (true);  free(peer); }
//here is the code for testing //here is the code for testing //here is the code for testing //here is the code for testing //here is the code for testing std::list<PeerSocket*> peers; void ServerAccept(SOCKET* server, SOCKET* tcp) {  PeerSocket *peer = new PeerSocket();  peers.push_back(peer);  peer->server = server;  peer->tcp = tcp;
 sockaddr_in SenderAddr;  int addrlen = sizeof(sockaddr);  getpeername(*peer->tcp, (sockaddr*)&SenderAddr, &addrlen);  printf_s("开始从客户端%s:%d接收数据\n", inet_ntoa(SenderAddr.sin_addr), ntohs(SenderAddr.sin_port));  ServerReadAsyncLoop(peer); }
void ReceiveFrom(SOCKET* s, char* data, int len, char* IPAddr, int size) {  sockaddr_in name;  int addrlen = sizeof(sockaddr);  getsockname(*s, (sockaddr*)&name, &addrlen);  printf_s("%s:%d收到数据 来自%s, 数据:%s, 长度:%d\n", inet_ntoa(name.sin_addr), ntohs(name.sin_port), IPAddr, data, len); }
void Receive(SOCKET* s, char* data, int len) {  sockaddr_in name;  int addrlen = sizeof(sockaddr);  getsockname(*s, (sockaddr*)&name, &addrlen);  printf_s("%s:%d收到数据 数据:%s, 长度:%d\n", inet_ntoa(name.sin_addr), ntohs(name.sin_port), data, len); }
int main() {  Init();
 //nonblocking mode  int type = 0;  printf_s("选择类型1.TCP Client\t2.TCP Server\t3.UDP Client\n");  scanf_s("%d",&type);  int port = 0;  printf_s("输入要绑定的端口\n");  scanf_s("%d", &port);  switch (type)  {  case 1:  {   SOCKET* tcp = CreateTCPClient((unsigned short)port);   char ip[16] = {0};   int tport = 0;   printf_s("输入目标IP 目标端口\n");   scanf_s("%s%d", ip, 16, &tport);      TCPConnectToServer(tcp, ip, tport);   SetTCPReceiveCallBack(Receive);   TCPReadAsyncLoop(tcp);
  for (;;)   {    char data[256];    printf_s("输入发送的内容\n");    gets_s(data, 256);    TCPSendToServer(tcp, data, strnlen_s(data, 256));   }
  break;  }  case 2:  {   SOCKET* server = CreateTCPServer((unsigned short)port);   SetServerAcceptCallBack(ServerAccept);   SetServerReceiveCallBack(ReceiveFrom);   ServerListenAcceptAsync(server, 16);   for (;;)   {    char data[256];    printf_s("输入要向所有客户端发送的内容\n");    gets_s(data, 256);    for (std::list<PeerSocket*>::iterator itr = peers.begin();     itr != peers.end(); itr++)    {     ServerSend(*itr, data, strnlen_s(data, 256));    }   }   break;  }  case 3:  {   SOCKET* udp = CreateUDPClient((unsigned short)port);   SetUDPReceiveCallBack(ReceiveFrom);   UDPReadAsyncLoop(udp);   for (;;)   {    char ip[16] = { 0 };    int tport = 0;    printf_s("输入目标IP 目标端口\n");    scanf_s("%s%d", ip,16 &tport);    char data[256];    printf_s("输入发送的内容\n");    gets_s(data, 256);    UDPSendTo(udp, data, strnlen_s(data, 256),ip,tport);   }   break;  }  default:   break;  }    return 0; }

编译为USocket.DLL 

.h头文件暴露API接口

#pragma once

#define DLL
#ifdef DLL
#include <WinSock2.h>
#define API __declspec(dllexport)
#else
#define SOCKET void
#define API __declspec(dllimport)
#endif

typedef struct
{
	SOCKET* server;
	SOCKET* tcp;
}*LPPeerSocket, PeerSocket;

typedef void OnReceive(SOCKET*, char*, int);
typedef void OnReceiveForm(SOCKET*, char*, int, char*, int);

typedef void OnServerAccept(SOCKET*, SOCKET*);

extern "C"
{
	API void Init();
	API void OpenConsole();
	API void CloseConsole();
	API void Shutdown();
	API SOCKET* CreateTCPClient(unsigned short port);
	API SOCKET* CreateTCPServer(unsigned short port);
	API void ServerListenAccept(SOCKET* server, int maxconn);
	API void ServerListenAcceptAsync(SOCKET* server, int maxconn);
	API SOCKET* CreateUDPClient(unsigned short port);
	API int SocketIONonBlocking(SOCKET* s, int mode);
	API int TCPConnectToServer(SOCKET* sockClient, char* IP, unsigned short port);
	API void SetTCPReceiveCallBack(OnReceive* func);
	API void SetUDPReceiveCallBack(OnReceiveForm* func);
	API void SetServerAcceptCallBack(OnServerAccept* func);
	API void SetServerReceiveCallBack(OnReceiveForm* func);
	API void UDPReadAsyncLoop(SOCKET* s);
	API void TCPReadAsyncLoop(SOCKET* s);
	API void ServerReadAsyncLoop(PeerSocket* peer);
	API int TCPReceive(SOCKET* client, char* data, int* datasize);
	API int UDPReceive(SOCKET* client, char* data, int* datasize, char* outfrom, int* port);
	API int ServerReceive(PeerSocket* peer, char* data, int* datasize);
	API int TCPSendToServer(SOCKET* client, char* data, int len);
	API int ServerSend(PeerSocket* peer, char* data, int len);
	API int UDPSendTo(SOCKET* client, char* data, int len, char* IP, int port);
	API int Close(SOCKET* s);
}

LIBUSOCKET.h 为UE4接入API,继承于蓝图函数库

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#define SOCKET void

#include "Kismet/BlueprintFunctionLibrary.h"
#include "LibUSocket.generated.h"


typedef struct
{
	SOCKET* server;
	SOCKET* tcp;
}*LPPeerSocket, PeerSocket;

typedef void OnReceive(void*, char*, int);
typedef void OnReceiveForm(void*, char*, int, char*, int);
typedef void OnServerAccept(void*, void*);

/**
 * 
 */
UCLASS()
class LEARN_API ULibUSocket : public UBlueprintFunctionLibrary
{
public:
	static void Init();
	static void OpenConsole();
	static void CloseConsole();
	static void Shutdown();
	static SOCKET* CreateTCPClient(int port);
	static SOCKET* CreateTCPServer(int);
	static void ServerListenAccept(SOCKET*, int);
	static void ServerListenAcceptAsync(SOCKET*, int);
	static SOCKET* CreateUDPClient(int);
	static int SocketIONonBlocking(SOCKET*, int);
	static int TCPConnectToServer(SOCKET*, char*, int);
	static void SetTCPReceiveCallBack(OnReceive*);
	static void SetUDPReceiveCallBack(OnReceiveForm*);
	static void SetServerAcceptCallBack(OnServerAccept*);
	static void SetServerReceiveCallBack(OnReceiveForm*);
	static void UDPReadAsyncLoop(SOCKET*);
	static void TCPReadAsyncLoop(SOCKET*);
	static void ServerReadAsyncLoop(PeerSocket*);
	static int TCPReceive(SOCKET*, char*, int*);
	static int UDPReceive(SOCKET*, char*, int*, char*, int*);
	static int ServerReceive(PeerSocket*, char*, int*);
	static void TCPSendToServer(SOCKET*, char*, int);
	static void ServerSend(PeerSocket*, char*, int);
	static void UDPSendTo(SOCKET*, char*, int, char*, int);
	static void Close(SOCKET*);
	GENERATED_BODY()//下面的写的是虚幻的规范。SOCKET* char* int* 都是不允许的
};


LibUSocket.cpp 虚幻DLL调用实现

// Fill out your copyright notice in the Description page of Project Settings.

#include "Learn.h"
#include "LibUSocket.h"
const TCHAR* DLLNAME = L"USocket.dll";

typedef void fInit();
typedef void fOpenConsole();
typedef void fCloseConsole();
typedef void fShutdown();
typedef SOCKET* fCreateTCPClient(unsigned short port);
typedef SOCKET* fCreateTCPServer(unsigned short port);
typedef void fServerListenAccept(SOCKET* server, int maxconn);
typedef void fServerListenAcceptAsync(SOCKET* server, int maxconn);
typedef SOCKET* fCreateUDPClient(unsigned short port);
typedef int fSocketIONonBlocking(SOCKET* s, int mode);
typedef int fTCPConnectToServer(SOCKET* sockClient, char* IP, unsigned short port);
typedef void fSetTCPReceiveCallBack(OnReceive* func);
typedef void fSetUDPReceiveCallBack(OnReceiveForm* func);
typedef void fSetServerAcceptCallBack(OnServerAccept* func);
typedef void fSetServerReceiveCallBack(OnReceiveForm* func);
typedef void fUDPReadAsyncLoop(SOCKET* s);
typedef void fTCPReadAsyncLoop(SOCKET* s);
typedef void fServerReadAsyncLoop(PeerSocket* peer);
typedef int fTCPReceive(SOCKET* client, char* data, int* datasize);
typedef int fUDPReceive(SOCKET* client, char* data, int* datasize, char* outfrom, int* port);
typedef int fServerReceive(PeerSocket* peer, char* data, int* datasize);
typedef int fTCPSendToServer(SOCKET* client, char* data, int len);
typedef int fServerSend(PeerSocket* peer, char* data, int len);
typedef int fUDPSendTo(SOCKET* client, char* data, int len, char* IP, int port);
typedef int fClose(SOCKET* s);

void ULibUSocket::Init()
{
	FString filePath = FPaths::GamePluginsDir() + (FString)DLLNAME;
	void *v_dllHandle = FPlatformProcess::GetDllHandle(*filePath);
	if (!v_dllHandle) return;
	FString procName = "Init";
	fInit* func = (fInit*)FPlatformProcess::GetDllExport(v_dllHandle, *procName);
	if (func != NULL)
	{
		func();
	}
}

void ULibUSocket::OpenConsole()
{
	FString filePath = FPaths::GamePluginsDir() + (FString)DLLNAME;
	void *v_dllHandle = FPlatformProcess::GetDllHandle(*filePath);
	if (!v_dllHandle) return;
	FString procName = "OpenConsole";
	fOpenConsole* func = (fOpenConsole*)FPlatformProcess::GetDllExport(v_dllHandle, *procName);
	if (func != NULL)
	{
		func();
	}
}

void ULibUSocket::CloseConsole()
{
	FString filePath = FPaths::GamePluginsDir() + (FString)DLLNAME;
	void *v_dllHandle = FPlatformProcess::GetDllHandle(*filePath);
	if (!v_dllHandle) return;
	FString procName = "CloseConsole";
	fCloseConsole* func = (fCloseConsole*)FPlatformProcess::GetDllExport(v_dllHandle, *procName);
	if (func != NULL)
	{
		func();
	}
}

void ULibUSocket::Shutdown()
{
	FString filePath = FPaths::GamePluginsDir() + (FString)DLLNAME;
	void *v_dllHandle = FPlatformProcess::GetDllHandle(*filePath);
	if (!v_dllHandle) return;
	FString procName = "Shutdown";
	fShutdown* func = (fShutdown*)FPlatformProcess::GetDllExport(v_dllHandle, *procName);
	if (func != NULL)
	{
		func();
	}
}

SOCKET * ULibUSocket::CreateTCPClient(int port)
{
	FString filePath = FPaths::GamePluginsDir() + (FString)DLLNAME;
	void *v_dllHandle = FPlatformProcess::GetDllHandle(*filePath);
	if (!v_dllHandle) return nullptr;
	FString procName = "CreateTCPClient";
	fCreateTCPClient* func = (fCreateTCPClient*)FPlatformProcess::GetDllExport(v_dllHandle, *procName);
	if (func != NULL)
	{
		return func(port);
	}
	return nullptr;
}

SOCKET * ULibUSocket::CreateTCPServer(int port)
{
	FString filePath = FPaths::GamePluginsDir() + (FString)DLLNAME;
	void *v_dllHandle = FPlatformProcess::GetDllHandle(*filePath);
	if (!v_dllHandle) return nullptr;
	FString procName = "CreateTCPServer";
	fCreateTCPServer* func = (fCreateTCPServer*)FPlatformProcess::GetDllExport(v_dllHandle, *procName);
	if (func != NULL)
	{
		return func(port);
	}
	return nullptr;
}

void ULibUSocket::ServerListenAccept(SOCKET* server, int maxconn)
{
	FString filePath = FPaths::GamePluginsDir() + (FString)DLLNAME;
	void *v_dllHandle = FPlatformProcess::GetDllHandle(*filePath);
	if (!v_dllHandle) return;
	FString procName = "ServerListenAccept";
	fServerListenAccept* func = (fServerListenAccept*)FPlatformProcess::GetDllExport(v_dllHandle, *procName);
	if (func != NULL)
	{
		func(server, maxconn);
	}
}

void ULibUSocket::ServerListenAcceptAsync(SOCKET* server, int maxconn)
{
	FString filePath = FPaths::GamePluginsDir() + (FString)DLLNAME;
	void *v_dllHandle = FPlatformProcess::GetDllHandle(*filePath);
	if (!v_dllHandle) return;
	FString procName = "ServerListenAcceptAsync";
	fServerListenAcceptAsync* func = (fServerListenAcceptAsync*)FPlatformProcess::GetDllExport(v_dllHandle, *procName);
	if (func != NULL)
	{
		func(server, maxconn);
	}
}

SOCKET * ULibUSocket::CreateUDPClient(int port)
{
	FString filePath = FPaths::GamePluginsDir() + (FString)DLLNAME;
	void *v_dllHandle = FPlatformProcess::GetDllHandle(*filePath);
	if (!v_dllHandle) return nullptr;
	FString procName = "CreateUDPClient";
	fCreateUDPClient* func = (fCreateUDPClient*)FPlatformProcess::GetDllExport(v_dllHandle, *procName);
	if (func != NULL)
	{
		return func(port);
	}
	return nullptr;
}

int ULibUSocket::SocketIONonBlocking(SOCKET* socket, int mode)
{
	FString filePath = FPaths::GamePluginsDir() + (FString)DLLNAME;
	void *v_dllHandle = FPlatformProcess::GetDllHandle(*filePath);
	if (!v_dllHandle) return 0;
	FString procName = "SocketIONonBlocking";
	fSocketIONonBlocking* func = (fSocketIONonBlocking*)FPlatformProcess::GetDllExport(v_dllHandle, *procName);
	if (func != NULL)
	{
		return func(socket, mode);
	}
	return 0;
}

int ULibUSocket::TCPConnectToServer(SOCKET* socket, char* IP, int port)
{
	FString filePath = FPaths::GamePluginsDir() + (FString)DLLNAME;
	void *v_dllHandle = FPlatformProcess::GetDllHandle(*filePath);
	if (!v_dllHandle) return 0;
	FString procName = "TCPConnectToServer";
	fTCPConnectToServer* func = (fTCPConnectToServer*)FPlatformProcess::GetDllExport(v_dllHandle, *procName);
	if (func != NULL)
	{
		return func(socket, IP, port);
	}
	return 0;
}

void ULibUSocket::SetTCPReceiveCallBack(OnReceive *f)
{
	FString filePath = FPaths::GamePluginsDir() + (FString)DLLNAME;
	void *v_dllHandle = FPlatformProcess::GetDllHandle(*filePath);
	if (!v_dllHandle) return;
	FString procName = "SetTCPReceiveCallBack";
	fSetTCPReceiveCallBack* func = (fSetTCPReceiveCallBack*)FPlatformProcess::GetDllExport(v_dllHandle, *procName);
	if (func != NULL)
	{
		func(f);
	}
}

void ULibUSocket::SetUDPReceiveCallBack(OnReceiveForm *f)
{
	FString filePath = FPaths::GamePluginsDir() + (FString)DLLNAME;
	void *v_dllHandle = FPlatformProcess::GetDllHandle(*filePath);
	if (!v_dllHandle) return ;
	FString procName = "SetUDPReceiveCallBack";
	fSetUDPReceiveCallBack* func = (fSetUDPReceiveCallBack*)FPlatformProcess::GetDllExport(v_dllHandle, *procName);
	if (func != NULL)
	{
		func(f);
	}
}

void ULibUSocket::SetServerAcceptCallBack(OnServerAccept *f)
{
	FString filePath = FPaths::GamePluginsDir() + (FString)DLLNAME;
	void *v_dllHandle = FPlatformProcess::GetDllHandle(*filePath);
	if (!v_dllHandle) return;
	FString procName = "SetServerAcceptCallBack";
	fSetServerAcceptCallBack* func = (fSetServerAcceptCallBack*)FPlatformProcess::GetDllExport(v_dllHandle, *procName);
	if (func != NULL)
	{
		func(f);
	}
}

void ULibUSocket::SetServerReceiveCallBack(OnReceiveForm *f)
{
	FString filePath = FPaths::GamePluginsDir() + (FString)DLLNAME;
	void *v_dllHandle = FPlatformProcess::GetDllHandle(*filePath);
	if (!v_dllHandle) return;
	FString procName = "SetServerReceiveCallBack";
	fSetServerReceiveCallBack* func = (fSetServerReceiveCallBack*)FPlatformProcess::GetDllExport(v_dllHandle, *procName);
	if (func != NULL)
	{
		func(f);
	}
}

void ULibUSocket::UDPReadAsyncLoop(SOCKET* f)
{
	FString filePath = FPaths::GamePluginsDir() + (FString)DLLNAME;
	void *v_dllHandle = FPlatformProcess::GetDllHandle(*filePath);
	if (!v_dllHandle) return;
	FString procName = "UDPReadAsyncLoop";
	fUDPReadAsyncLoop* func = (fUDPReadAsyncLoop*)FPlatformProcess::GetDllExport(v_dllHandle, *procName);
	if (func != NULL)
	{
		func(f);
	}
}

void ULibUSocket::TCPReadAsyncLoop(SOCKET* socket)
{
	FString filePath = FPaths::GamePluginsDir() + (FString)DLLNAME;
	void *v_dllHandle = FPlatformProcess::GetDllHandle(*filePath);
	if (!v_dllHandle) return;
	FString procName = "TCPReadAsyncLoop";
	fTCPReadAsyncLoop* func = (fTCPReadAsyncLoop*)FPlatformProcess::GetDllExport(v_dllHandle, *procName);
	if (func != NULL)
	{
		func(socket);
	}
}

void ULibUSocket::ServerReadAsyncLoop(PeerSocket* peer)
{
	FString filePath = FPaths::GamePluginsDir() + (FString)DLLNAME;
	void *v_dllHandle = FPlatformProcess::GetDllHandle(*filePath);
	if (!v_dllHandle) return;
	FString procName = "ServerReadAsyncLoop";
	fServerReadAsyncLoop* func = (fServerReadAsyncLoop*)FPlatformProcess::GetDllExport(v_dllHandle, *procName);
	if (func != NULL)
	{
		func(peer);
	}
}

int ULibUSocket::TCPReceive(SOCKET* socket, char* data, int* size)
{
	FString filePath = FPaths::GamePluginsDir() + (FString)DLLNAME;
	void *v_dllHandle = FPlatformProcess::GetDllHandle(*filePath);
	if (!v_dllHandle) return 0;
	FString procName = "TCPReceive";
	fTCPReceive* func = (fTCPReceive*)FPlatformProcess::GetDllExport(v_dllHandle, *procName);
	if (func != NULL)
	{
		return func(socket, data, size);
	}
	return 0;
}

int ULibUSocket::UDPReceive(SOCKET* socket, char* data, int* size, char* IP, int* port)
{
	FString filePath = FPaths::GamePluginsDir() + (FString)DLLNAME;
	void *v_dllHandle = FPlatformProcess::GetDllHandle(*filePath);
	if (!v_dllHandle) return 0;
	FString procName = "UDPReceive";
	fUDPReceive* func = (fUDPReceive*)FPlatformProcess::GetDllExport(v_dllHandle, *procName);
	if (func != NULL)
	{
		return func(socket, data, size, IP, port);
	}
	return 0;
}

int ULibUSocket::ServerReceive(PeerSocket* peer, char* data, int* size)
{
	FString filePath = FPaths::GamePluginsDir() + (FString)DLLNAME;
	void *v_dllHandle = FPlatformProcess::GetDllHandle(*filePath);
	if (!v_dllHandle) return 0;
	FString procName = "ServerReceive";
	fServerReceive* func = (fServerReceive*)FPlatformProcess::GetDllExport(v_dllHandle, *procName);
	if (func != NULL)
	{
		return func(peer, data, size);
	}
	return 0;
}

void ULibUSocket::TCPSendToServer(SOCKET* socket, char* data, int size)
{
	FString filePath = FPaths::GamePluginsDir() + (FString)DLLNAME;
	void *v_dllHandle = FPlatformProcess::GetDllHandle(*filePath);
	if (!v_dllHandle) return;
	FString procName = "TCPSendToServer";
	fTCPSendToServer* func = (fTCPSendToServer*)FPlatformProcess::GetDllExport(v_dllHandle, *procName);
	if (func != NULL)
	{
		func(socket, data, size);
	}
}

void ULibUSocket::ServerSend(PeerSocket* peer, char* data, int size)
{
	FString filePath = FPaths::GamePluginsDir() + (FString)DLLNAME;
	void *v_dllHandle = FPlatformProcess::GetDllHandle(*filePath);
	if (!v_dllHandle) return;
	FString procName = "ServerSend";
	fServerSend* func = (fServerSend*)FPlatformProcess::GetDllExport(v_dllHandle, *procName);
	if (func != NULL)
	{
		func(peer, data, size);
	}
}

void ULibUSocket::UDPSendTo(SOCKET* socket, char* data, int size, char* IP, int port)
{
	FString filePath = FPaths::GamePluginsDir() + (FString)DLLNAME;
	void *v_dllHandle = FPlatformProcess::GetDllHandle(*filePath);
	if (!v_dllHandle) return;
	FString procName = "UDPSendTo";
	fUDPSendTo* func = (fUDPSendTo*)FPlatformProcess::GetDllExport(v_dllHandle, *procName);
	if (func != NULL)
	{
		func(socket, data, size, IP, port);
	}
}

void ULibUSocket::Close(SOCKET* socket)
{
	FString filePath = FPaths::GamePluginsDir() + (FString)DLLNAME;
	void *v_dllHandle = FPlatformProcess::GetDllHandle(*filePath);
	if (!v_dllHandle) return;
	FString procName = "Close";
	fClose* func = (fClose*)FPlatformProcess::GetDllExport(v_dllHandle, *procName);
	if (func != NULL)
	{
		func(socket);
	}
}

组件使用接口,非阻塞模式

// Fill out your copyright notice in the Description page of Project Settings.

#include "Learn.h"
#include "ClientSocketComponent.h"
#include "Kismet/KismetSystemLibrary.h"


//#include "Interface_Selectable.h"
// Sets default values for this component's properties
UClientSocketComponent::UClientSocketComponent()
{
	// Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features
	// off to improve performance if you don't need them.
	PrimaryComponentTick.bCanEverTick = true;
	// ...
}

// Called when the game starts
void UClientSocketComponent::BeginPlay()
{
	Super::BeginPlay();
	ULibUSocket::Init();
	tcp = ULibUSocket::CreateTCPClient(LocalPort);
	ULibUSocket::TCPConnectToServer(tcp, (char*)*IPAddress, Port);
	ULibUSocket::SocketIONonBlocking(tcp, 1);//非阻塞模式
	const char* ID = "DISPLAY";
	ULibUSocket::TCPSendToServer(tcp, (char*)ID, sizeof(ID));//
	// ...
}

void UClientSocketComponent::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
	ULibUSocket::Close(tcp);
	ULibUSocket::Shutdown();
}


// Called every frame
void UClientSocketComponent::TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction )
{
	char data[1024];
	int len = 1024;
	int result = ULibUSocket::TCPReceive(tcp, data, &len);
	if (result == 0)
	{
		//printf_s("data:%s\n", data);
		UKismetSystemLibrary::PrintString(this, (FString)data);
	}
	// ...
}

void UClientSocketComponent::ClientOnReceive_Implementation(const FString& data)
{
	//TSet<UActorComponent*> coms = actorWithMediaCOM->GetComponents();
	//if (coms.Num() <= 0)return;
	/*for (UActorComponent* com : coms)
	{
		IInterface_Selectable* s = Cast<IInterface_Selectable>(com);//判断组件是否实现了接口,方式不可用
		//UKismetSystemLibrary::PrintString(this, com->GetName());
		if (s)
			s->Execute_OnSelect(actorWithMediaCOM, data);
	}*/

	/*for (UActorComponent* com : coms)
	{
		bool impSelectable = com->GetClass()->ImplementsInterface(UInterface_Selectable::StaticClass());
		if (impSelectable)
		{
			IInterface_Selectable::Execute_OnSelect(com, data);
		}
	}*/
}



 类似资料: