【UE4学习】17_Socket测试

来源:互联网 发布:慧博智能策略终端mac 编辑:程序博客网 时间:2024/06/05 02:21

目录:

    • 概述
    • 纯win32 console application客户端 服务端 阻塞通信
    • win32 console application 服务端 UE4客户端


概述

本次仅作简单测试,尚未进行多线程测试。

环境:

  • win10 64bit
  • UE4.15

纯win32 console application客户端 / 服务端 (阻塞通信)

服务端测试代码:

// SocketTest.cpp : Defines the entry point for the console application.#include "stdafx.h"#include <stdio.h>#include <string>#include <iostream>#include <WinSock2.h>#include<WS2tcpip.h>#pragma comment(lib,"WS2_32.lib")using namespace std;int main(){    WSADATA wsaData;    SOCKET serverSock;    SOCKADDR_IN serverAddr;    SOCKET clientSock;    SOCKADDR_IN clientAddr;    cout << "Server Start!" << endl;    int err=WSAStartup(MAKEWORD(2, 2), &wsaData);    if (0 != err)    {        cout << "WSAStartup failed!" << endl;        return 1;    }    serverSock = socket(AF_INET, SOCK_STREAM, 0);    serverAddr.sin_family = AF_INET;    serverAddr.sin_port = htons(4399);    serverAddr.sin_addr.S_un.S_addr = INADDR_ANY;    int retVal = bind(serverSock, (SOCKADDR*)&serverAddr, sizeof(serverAddr));    if (SOCKET_ERROR == retVal)    {        cout << "bind failed!" << endl;        closesocket(serverSock);        WSACleanup();        return -1;    }    retVal = listen(serverSock, 5);    if (SOCKET_ERROR == retVal)    {        cout << "listen failed!" << endl;        closesocket(serverSock);        WSACleanup();        return -1;    }    int addrClientlen = sizeof(clientAddr);    clientSock = accept(serverSock, (SOCKADDR*)&clientAddr, &addrClientlen);    while (1)    {        char sendBuff[50];        //sprintf_s(sendBuff, "welcome %s to here", inet_ntoa(clientAddr.sin_addr));        char IPdotdec[20] = { '\0' };        inet_ntop(AF_INET, (void*)&clientAddr.sin_addr, IPdotdec, 16);        sprintf_s(sendBuff, "From Server: welcome %s to here", IPdotdec);        send(clientSock, sendBuff, strlen(sendBuff) + 1, 0);        char recvBuff[50];        recv(clientSock, recvBuff, 50, 0);        printf(" %s \n\n", recvBuff);        Sleep(1000);    }    closesocket(serverSock);    WSACleanup();    return 0;}

客户端测试代码:

// ClientTest.cpp : Defines the entry point for the console application.#include "stdafx.h"#define _WINSOCK_DEPRECATED_NO_WARNINGS#include <iostream>#include <WinSock2.h>#include<WS2tcpip.h>#pragma comment(lib,"WS2_32.lib")using namespace std;int main(){    WSADATA wsaData;    SOCKET serverSock;    SOCKADDR_IN serverAddr;    SOCKET hostSock;    SOCKADDR_IN hostAddr;    const int BUF_SIZE = 64;    char buf[BUF_SIZE]; //接收数据缓冲区      char bufRecv[BUF_SIZE];    int retVal;    cout << "Client Start!" << endl;    int err = WSAStartup(MAKEWORD(2, 2), &wsaData);    if (0 != err)    {        cout << "WSAStartup failed!" << endl;        return 1;    }    hostSock= socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);    serverAddr.sin_family = AF_INET;    serverAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");    serverAddr.sin_port = htons(4399);    int serverAddrLen = sizeof(serverAddr);    retVal = connect(hostSock, (SOCKADDR*)&serverAddr, serverAddrLen);    if (SOCKET_ERROR == retVal)    {        cout << "connect failed!" << endl;        closesocket(hostSock);        WSACleanup();        return -1;    }    int index = 0;    while (true)    {        char sendBuff[50];        sprintf_s(sendBuff, "From Client: num %d ", index);        send(hostSock, sendBuff, strlen(sendBuff) + 1, 0);        char recvBuff[50];        recv(hostSock, recvBuff, 50, 0);        printf(" %s \n\n", recvBuff);        Sleep(1000);        index++;    }    getchar();    closesocket(hostSock);    WSACleanup();    return 0;}

效果:
这里写图片描述


win32 console application 服务端 / UE4客户端

创建SocketActor C++ Class

UE4 C++工程的 .build.cs

using UnrealBuildTool;public class SocketAndJsonTest : ModuleRules{    public SocketAndJsonTest(TargetInfo Target)    {        PublicDependencyModuleNames.AddRange(                                    new string[] {                                        "Core",                                        "CoreUObject",                                        "Engine",                                        "InputCore",                                        "Sockets",//添加这两个                                        "Networking"                                    });        PrivateDependencyModuleNames.AddRange(new string[] {  });    }}

SocketActor.h

#pragma once#include "GameFramework/Actor.h"#include "Networking.h"#include "SocketActor.generated.h"UCLASS()class SOCKETANDJSONTEST_API ASocketActor : public AActor{    GENERATED_BODY()public:     // Sets default values for this actor's properties    ASocketActor();protected:    // Called when the game starts or when spawned    virtual void BeginPlay() override;public:     // Called every frame    virtual void Tick(float DeltaTime) override;    UFUNCTION(BlueprintCallable, Category = "MySocket")        bool SocketCreate(FString IPStr, int32 port);    UFUNCTION(BlueprintCallable, Category = "MySocket")        void SocketSend(FString meesage);    UFUNCTION(BlueprintCallable, Category = "MySocket")        bool SocketReceive();    FString StringFromBinaryArray(TArray<uint8> BinaryArray);    FSocket *Host;    FIPv4Address ip;};

SocketActor.cpp

// Fill out your copyright notice in the Description page of Project Settings.#include "SocketAndJsonTest.h"#include "SocketActor.h"// Sets default valuesASocketActor::ASocketActor(){    // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.    PrimaryActorTick.bCanEverTick = true;}// Called when the game starts or when spawnedvoid ASocketActor::BeginPlay(){    Super::BeginPlay();}// Called every framevoid ASocketActor::Tick(float DeltaTime){    Super::Tick(DeltaTime);}bool ASocketActor::SocketCreate(FString IPStr, int32 port){    FIPv4Address::Parse(IPStr, ip);    TSharedRef<FInternetAddr> addr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();    addr->SetIp(ip.Value);    addr->SetPort(port);    Host = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateSocket(NAME_Stream, TEXT("default"), false);    if (Host->Connect(*addr))    {        GEngine->AddOnScreenDebugMessage(1, 2.0f, FColor::Green, TEXT("Connect Succ!"));        UE_LOG(LogTemp, Warning, TEXT("Connect Succ!"));        return true;        /*        FString seriallized = TEXT("LoadPlayer|1");        TCHAR *seriallizedChar = seriallized.GetCharArray().GetData();        int32 size = FCString::Strlen(seriallizedChar);        int32 sent = 0;        if (Host->Send((uint8*)TCHAR_TO_UTF8(seriallizedChar),size,sent))        {            GEngine->AddOnScreenDebugMessage(1, 2.0f, FColor::Green, TEXT("_____Send Succ!"));            UE_LOG(LogTemp, Warning, TEXT("_____Send Succ!"));        }        else        {            GEngine->AddOnScreenDebugMessage(1, 2.0f, FColor::Green, TEXT("_____Send Succ!"));            UE_LOG(LogTemp, Warning, TEXT("_____Send Succ!"));        }        */    }    else    {        GEngine->AddOnScreenDebugMessage(1, 2.0f, FColor::Green, TEXT("Connect failed!"));        UE_LOG(LogTemp, Warning, TEXT("Connect failed!"));        return false;    }}void ASocketActor::SocketSend(FString meesage){    //FString seriallized = TEXT("LoadPlayer|1");    TCHAR *seriallizedChar = meesage.GetCharArray().GetData();    int32 size = FCString::Strlen(seriallizedChar)+1;    int32 sent = 0;    if (Host->Send((uint8*)TCHAR_TO_UTF8(seriallizedChar), size, sent))    {        GEngine->AddOnScreenDebugMessage(1, 2.0f, FColor::Green, TEXT("_____Send Succ!"));        UE_LOG(LogTemp, Warning, TEXT("_____Send Succ!"));    }    else    {        GEngine->AddOnScreenDebugMessage(1, 2.0f, FColor::Green, TEXT("_____Send failed!"));        UE_LOG(LogTemp, Warning, TEXT("_____Send failed!"));    }}bool ASocketActor::SocketReceive(){    if (!Host)    {        return false;    }    TArray<uint8> ReceiveData;    uint32 size;    uint8 element = 0;    while (Host->HasPendingData(size))    {        ReceiveData.Init(element,FMath::Min(size, 65507u));        int32 read = 0;        Host->Recv(ReceiveData.GetData(), ReceiveData.Num(), read);    }    if (ReceiveData.Num()<=0)    {        return false;    }    FString log= "Total Data read! num: "+FString::FromInt(ReceiveData.Num() <= 0);    GEngine->AddOnScreenDebugMessage(1, 2.0f, FColor::Green, log);    UE_LOG(LogTemp, Warning, TEXT("Recv log:   %s"), *log);    const FString ReceivedUE4String = StringFromBinaryArray(ReceiveData);    log = "Server:" + ReceivedUE4String;    GEngine->AddOnScreenDebugMessage(1, 2.0f, FColor::Green, log);    UE_LOG(LogTemp, Warning, TEXT("*** %s"), *log);    return true;}FString ASocketActor::StringFromBinaryArray(TArray<uint8> BinaryArray){    return FString(ANSI_TO_TCHAR(reinterpret_cast<const char*>(BinaryArray.GetData())));}

UE4 蓝图
这里写图片描述

效果
这里写图片描述

参考

  • win32 console application部分:

    • http://blog.csdn.net/yaopeng_2005/article/details/6696105
    • http://blog.csdn.net/orange_xxx/article/details/7276868
    • http://blog.csdn.net/rexuefengye/article/details/12145569
  • UE4部分:

    • https://wiki.unrealengine.com/Third_Party_Socket_Server_Connection
    • https://wiki.unrealengine.com/TCP_Socket_Listener,Receive_Binary_Data_From_an_IP/Port_Into_UE4,(Full_Code_Sample)
0 0
原创粉丝点击