我正在尝试使用
SteamNetworkingSockets->ConnectP2P
连接两个对等点,这应该在两个对等点之间建立数据报中继。
我的服务器使用 CreateListenSocketP2P
,客户端使用 ConnectP2P 和 SteamNetworkingIdentity。
问题是客户端无法连接,我不确定为什么。我让服务器运行并且 API 加载它能够显示我的 steam id 但连接拒绝..
#include <iostream>
#include <steam/steam_api.h>
#include <steam/isteamnetworking.h>
#include <steam/isteamfriends.h>
#include <steam/isteamnetworkingmessages.h>
#include <steam/isteamnetworkingsockets.h>
#include <steam/isteamnetworkingutils.h>
#include <thread>
#include <assert.h>
#define VALID_64_STEAMID 0xFFFFFFFFFFFFFFFF
bool g_bQuit = false;
class Client {
public:
SteamNetworkingIdentity sni;
ISteamNetworkingSockets* m_pInterface;
HSteamNetConnection m_hConnection;
Client() {
memset(&sni, 0, sizeof(SteamNetworkingIdentity));
sni.m_eType = k_ESteamNetworkingIdentityType_SteamID;
sni.SetSteamID64(VALID_64_STEAMID);
if (sni.IsInvalid()) {
printf("invalid id\n");
exit(0);
}
m_pInterface = SteamNetworkingSockets();
SteamNetworkingConfigValue_t opt;
opt.SetPtr(k_ESteamNetworkingConfig_Callback_ConnectionStatusChanged, (void*)SteamNetConnectionStatusChangedCallback);
m_hConnection = m_pInterface->ConnectP2P(sni, 0, 1, &opt);
if (m_hConnection == k_HSteamNetConnection_Invalid) {
printf(":failed to connect\n");
exit(0);
}
}
void Run() {
while (!g_bQuit) {
PollIncomingMessages();
PollConnectionStateChanges();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
void PollIncomingMessages() {
while (!g_bQuit)
{
ISteamNetworkingMessage* pIncomingMsg = nullptr;
int numMsgs = m_pInterface->ReceiveMessagesOnConnection(m_hConnection, &pIncomingMsg, 1);
if (numMsgs == 0)
break;
if (numMsgs < 0) {
printf("Fatal error on incoming messages\n");
exit(0);
}
printf("message received\n");
// We don't need this anymore.
pIncomingMsg->Release();
}
}
void OnSteamNetConnectionStatusChanged(SteamNetConnectionStatusChangedCallback_t* pInfo)
{
assert(pInfo->m_hConn == m_hConnection || m_hConnection == k_HSteamNetConnection_Invalid);
// What's the state of the connection?
switch (pInfo->m_info.m_eState)
{
case k_ESteamNetworkingConnectionState_None:
// NOTE: We will get callbacks here when we destroy connections. You can ignore these.
break;
case k_ESteamNetworkingConnectionState_ClosedByPeer:
case k_ESteamNetworkingConnectionState_ProblemDetectedLocally:
{
g_bQuit = true;
// Print an appropriate message
if (pInfo->m_eOldState == k_ESteamNetworkingConnectionState_Connecting)
{
// Note: we could distinguish between a timeout, a rejected connection,
// or some other transport problem.
printf("Unable to connect to host", pInfo->m_info.m_szEndDebug);
}
else if (pInfo->m_info.m_eState == k_ESteamNetworkingConnectionState_ProblemDetectedLocally)
{
printf("Lost connection to host", pInfo->m_info.m_szEndDebug);
}
else
{
// NOTE: We could check the reason code for a normal disconnection
printf("The host hath bidden us farewell. (%s)", pInfo->m_info.m_szEndDebug);
}
// Clean up the connection. This is important!
// The connection is "closed" in the network sense, but
// it has not been destroyed. We must close it on our end, too
// to finish up. The reason information do not matter in this case,
// and we cannot linger because it's already closed on the other end,
// so we just pass 0's.
m_pInterface->CloseConnection(pInfo->m_hConn, 0, nullptr, false);
m_hConnection = k_HSteamNetConnection_Invalid;
break;
}
case k_ESteamNetworkingConnectionState_Connecting:
// We will get this callback when we start connecting.
// We can ignore this.
break;
case k_ESteamNetworkingConnectionState_Connected:
printf("Connected to server OK");
break;
default:
// Silences -Wswitch
break;
}
}
static Client* s_pCallbackInstance;
static void SteamNetConnectionStatusChangedCallback(SteamNetConnectionStatusChangedCallback_t* pInfo)
{
s_pCallbackInstance->OnSteamNetConnectionStatusChanged(pInfo);
}
void PollConnectionStateChanges()
{
s_pCallbackInstance = this;
m_pInterface->RunCallbacks();
}
};
Client* Client::s_pCallbackInstance = nullptr;
int main(int argc, const char* argv[]) {
// insert code here...
if (!SteamAPI_Init()) {
printf("Failed to initialize Steamworks SDK\n");
exit(1);
}
// Get local user Steam ID
CSteamID localID = SteamUser()->GetSteamID();
printf("Local user Steam ID: %llu\n", localID.ConvertToUint64());
printf("%s\n", SteamFriends()->GetPersonaName());
ISteamNetworkingUtils* utils;
utils = SteamNetworkingUtils();
utils->InitRelayNetworkAccess();
printf("Running client\n");
//run client
Client c;
c.Run();
SteamAPI_Shutdown();
return 0;
}
它尝试连接但随后打印
printf("Unable to connect to host", pInfo->m_info.m_szEndDebug);
里面
// Print an appropriate message
if (pInfo->m_eOldState == k_ESteamNetworkingConnectionState_Connecting)
{
// Note: we could distinguish between a timeout, a rejected connection,
// or some other transport problem.
printf("Unable to connect to host", pInfo->m_info.m_szEndDebug);
}
我很困惑为什么这会失败,Steam ID 也是有效的 0xFFFFFFFFFFFFFFFF 只是一个占位符..
有没有人有使用 SteamNetworkingSockets 和 SteamNetworkingIdentity 的经验,谁可以阐明点对点连接?