【UE4学习】17_Socket测试

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Szu_IT_Man/article/details/56838702

目录:


概述

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

环境:

  • 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 values
ASocketActor::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 spawned
void ASocketActor::BeginPlay()
{
    Super::BeginPlay();

}

// Called every frame
void 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 蓝图
这里写图片描述

效果
这里写图片描述

参考

展开阅读全文

没有更多推荐了,返回首页