最近公司项目要用广播通信 写了一个socket udp通信 最后项目还是用unity 没用上 所以拿出来和大家分享下
这个是接收端的
这个是客户端的 图上这个是发给指定ip的 要给局域网广播的话 将ip 改为255.255.255.255就好了
最后上源码
首先在Build. CS 里添加
PublicDependencyModuleNames.AddRange(new string[] {
"Core", "CoreUObject", "Engine", "InputCore",
"Sockets", "Networking" });
下面是 客户端 服务端的.h .cpp
[mw_shl_code=cpp,true]// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "Networking.h"
#include "GameFramework/Actor.h"
#include "RamaUDPSender.generated.h"
UCLASS()
class ARamaUDPSender : public AActor
{
GENERATED_UCLASS_BODY()
bool IsUDP;
UFUNCTION(BlueprintCallable, Category="UDP")
bool RamaUDPSender_SendString(FString ToSend);
public:
TSharedPtr<FInternetAddr> RemoteAddr;
FSocket* SenderSocket;
UFUNCTION(BlueprintCallable, Category = "UDP")
bool StartUDPSender(const FString& YourChosenSocketName,const FString& TheIP,const int32 ThePort,bool UDP);
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UDP")
bool ShowOnScreenDebugMessages;
//ScreenMsg
FORCEINLINE void ScreenMsg(const FString& Msg)
{
if (!ShowOnScreenDebugMessages) return;
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, *Msg);
}
FORCEINLINE void ScreenMsg(const FString& Msg, const float Value)
{
if (!ShowOnScreenDebugMessages) return;
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString:rintf(TEXT("%s %f"), *Msg, Value));
}
FORCEINLINE void ScreenMsg(const FString& Msg, const FString& Msg2)
{
if (!ShowOnScreenDebugMessages) return;
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString:rintf(TEXT("%s %s"), *Msg, *Msg2));
}
public:
/** Called whenever this actor is being removed from a level */
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
};[/mw_shl_code]
[mw_shl_code=cpp,true]// Fill out your copyright notice in the Description page of Project Settings.
#include "UDPSendReceive.h"
#include "RamaUDPSender.h"
ARamaUDPSender::ARamaUDPSender(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
SenderSocket = NULL;
ShowOnScreenDebugMessages = true;
}
void ARamaUDPSender::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
Super::EndPlay(EndPlayReason);
//~~~~~~~~~~~~~~~~
if (SenderSocket) //Clear all sockets!
{
SenderSocket->Close();
ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->DestroySocket(SenderSocket);
}
}
bool ARamaUDPSender::RamaUDPSender_SendString(FString ToSend) //发送消息处理
{
if (!SenderSocket)
{
ScreenMsg("No sender socket");
return false;
}
//~~~~~~~~~~~~~~~~
//发送消息
int32 BytesSent = 0;
FString serialized =ToSend;
TCHAR *serializedChar = serialized.GetCharArray().GetData();
int32 size = FCString::Strlen(serializedChar);
int32 sent = 0;
//SenderSocket->SendTo(Writer.GetData(), Writer.Num(), BytesSent, *RemoteAddr);
SenderSocket->SendTo((uint8*)TCHAR_TO_UTF8(serializedChar), size, BytesSent, *RemoteAddr);//发送给远端地址
if (BytesSent <= 0)
{
const FString Str = "Socket is valid but the receiver received 0 bytes, make sure it is listening properly!";
UE_LOG(LogTemp, Error, TEXT("%s"), *Str);
ScreenMsg(Str);
return false;
}
ScreenMsg("UDP Send Succcess! INFO Sent = ", ToSend);
return true;
}
bool ARamaUDPSender::StartUDPSender(const FString & YourChosenSocketName, const FString & TheIP, const int32 ThePort, bool UDP)///////////初始化远端IP 发送信息前
{
//FIPv4Endpoint Endpoint(FIPv4Address::Any, 6789);
//Create Remote Address.
RemoteAddr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
bool bIsValid;
RemoteAddr->SetIp(*TheIP, bIsValid);
RemoteAddr->SetPort(ThePort);
if (!bIsValid)
{
ScreenMsg("Rama UDP Sender>> IP address was not valid!", TheIP);
return false;
}
SenderSocket = FUdpSocketBuilder(*YourChosenSocketName)
.AsReusable()
.WithBroadcast()/////////////广播
.WithSendBufferSize(2 * 1024 * 1024)
//.BoundToEndpoint(Endpoint)
;
//check(SenderSocket->GetSocketType() == SOCKTYPE_Datagram);
//Set Send Buffer Size
int32 SendSize = 2 * 1024 * 1024;
SenderSocket->SetSendBufferSize(SendSize, SendSize);
SenderSocket->SetReceiveBufferSize(SendSize, SendSize);
if (bIsValid)
{
bIsValid = true;
}
return bIsValid;
}
[/mw_shl_code]
[mw_shl_code=cpp,true]// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "Networking.h"
#include "GameFramework/Actor.h"
#include "RamaUDPReceiver.generated.h"
UCLASS()
class ARamaUDPReceiver : public AActor
{
GENERATED_UCLASS_BODY()
public:
virtual void Tick(float DeltaSeconds) override;
//====================================================
public:
FSocket* ListenSocket;
FUdpSocketReceiver* UDPReceiver = nullptr;
UFUNCTION(BlueprintCallable, Category="UDP")
void StartUDPReceiver(const FString& YourChosenSocketName,const FString& TheIP,const int32 ThePort, bool& success);
UFUNCTION(BlueprintPure, Category = "UDP")
void DataRecv(FString& str,bool& success);
//ScreenMsg
FORCEINLINE void ScreenMsg(const FString& Msg)
{
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, *Msg);
}
FORCEINLINE void ScreenMsg(const FString& Msg, const float Value)
{
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString:rintf(TEXT("%s %f"), *Msg, Value));
}
FORCEINLINE void ScreenMsg(const FString& Msg, const FString& Msg2)
{
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString:rintf(TEXT("%s %s"), *Msg, *Msg2));
}
public:
/** Called whenever this actor is being removed from a level */
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
};
[/mw_shl_code]
[mw_shl_code=cpp,true]// Fill out your copyright notice in the Description page of Project Settings.
#include "UDPSendReceive.h"
#include "RamaUDPReceiver.h"
ARamaUDPReceiver::ARamaUDPReceiver(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
ListenSocket = NULL;
}
void ARamaUDPReceiver::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
Super::EndPlay(EndPlayReason);
//~~~~~~~~~~~~~~~~
delete UDPReceiver;
UDPReceiver = nullptr;
//Clear all sockets!
// makes sure repeat plays in Editor dont hold on to old sockets!
if (ListenSocket)
{
ListenSocket->Close();
ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->DestroySocket(ListenSocket);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//Start UDP Receiver
void ARamaUDPReceiver::StartUDPReceiver(const FString& YourChosenSocketName,const FString& TheIP,const int32 ThePort, bool& success) // 接收器初始化 接收信息前
{
TSharedRef<FInternetAddr> targetAddr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
FIPv4Address Addr;
FIPv4Address:arse(TheIP, Addr);
//Create Socket
FIPv4Endpoint Endpoint(FIPv4Address::Any, ThePort); //所有ip地址本地
//FIPv4Endpoint Endpoint(Addr, ThePort); //指定ip地址
ListenSocket = FUdpSocketBuilder(*YourChosenSocketName)
.AsNonBlocking()
.AsReusable()
.BoundToEndpoint(Endpoint)
.WithReceiveBufferSize(2 * 1024 * 1024)
;
//BUFFER SIZE
int32 BufferSize = 2 * 1024 * 1024;
ListenSocket->SetSendBufferSize(BufferSize, BufferSize);
ListenSocket->SetReceiveBufferSize(BufferSize, BufferSize);
if (!ListenSocket)
{
ScreenMsg("No socket");
success = false;
}
if (ListenSocket)
{
ScreenMsg("The receiver is initialized");
success = true;
}
//return true;
}
void ARamaUDPReceiver:ataRecv(FString& str, bool& success) //接收消息处理
{
if (!ListenSocket)
{
ScreenMsg("No sender socket");
success = false;
//return success;
}
TSharedRef<FInternetAddr> targetAddr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
TArray<uint8> ReceivedData;//定义一个接收器
uint32 Size;
if (ListenSocket->HasPendingData(Size))
{
success = true;
str = "";
uint8 *Recv = new uint8[Size];
int32 BytesRead = 0;
ReceivedData.SetNumUninitialized(FMath::Min(Size, 65507u));
ListenSocket->RecvFrom(ReceivedData.GetData(), ReceivedData.Num(), BytesRead, *targetAddr);//创建远程接收地址
char ansiiData[1024];
memcpy(ansiiData, ReceivedData.GetData(), BytesRead);//拷贝数据到接收器
ansiiData[BytesRead] = 0; //判断数据结束
FString debugData = ANSI_TO_TCHAR(ansiiData); //字符串转换
str = debugData;
// memset(ansiiData,0,1024);//清空
}
else
{
success = false;
}
//return success;
}
void ARamaUDPReceiver::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
}
[/mw_shl_code]
|