// 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);
}
}*/
}