Итак, основная функция выглядит так:
Код: Выделить всё
bool bServer = false;
bool bClient = false;
int nPort = DEFAULT_SERVER_PORT;
SteamNetworkingIPAddr addrServer; addrServer.Clear();
for (int i = 1; i < argc; ++i)
{
if (!bClient && !bServer)
{
if (!strcmp(argv[i], "client"))
{
bClient = true;
continue;
}
if (!strcmp(argv[i], "server"))
{
bServer = true;
continue;
}
}
if (!strcmp(argv[i], "--port"))
{
++i;
if (i >= argc)
PrintUsageAndExit();
nPort = atoi(argv[i]);
if (nPort 65535)
FatalError("Invalid port %d", nPort);
continue;
}
// Anything else, must be server address to connect to
if (bClient && addrServer.IsIPv6AllZeros())
{
if (!addrServer.ParseString(argv[i]))
FatalError("Invalid server address '%s'", argv[i]);
if (addrServer.m_port == 0)
addrServer.m_port = DEFAULT_SERVER_PORT;
continue;
}
PrintUsageAndExit();
}
if (bClient == bServer || (bClient && addrServer.IsIPv6AllZeros()))
PrintUsageAndExit();
// Create client and server sockets
InitSteamDatagramConnectionSockets();
LocalUserInput_Init();
if (bClient)
{
ChatClient client;
client.Run(addrServer);
}
else
{
ChatServer server;
server.Run((uint16)nPort);
}
ShutdownSteamDatagramConnectionSockets();
// Ug, why is there no simple solution for portable, non-blocking console user input?
// Just nuke the process
//LocalUserInput_Kill();
NukeProcess(0);
Стек вызовов выглядит следующим образом:
Код: Выделить всё
> Chat.exe!std::_Container_base12::_Orphan_all_unlocked_v3() Line 1349 C++
Chat.exe!std::_Container_base12::_Orphan_all_locked_v3() Line 1205 C++
Chat.exe!std::_Container_base12::_Orphan_all() Line 1364 C++
Chat.exe!std::string::_Tidy_deallocate() Line 4868 C++
Chat.exe!std::string::~basic_string() Line 3159 C++
Chat.exe!SteamNetworkingSocketsLib::CSteamNetworkConnectionBase::SetLocalCertUnsigned() Line 1314 C++
Chat.exe!SteamNetworkingSocketsLib::CSteamNetworkConnectionBase::BThinkCryptoReady(__int64 usecNow) Line 1090 C++
Chat.exe!SteamNetworkingSocketsLib::CSteamNetworkConnectionBase::InitConnectionCrypto(__int64 usecNow) Line 1029 C++
Chat.exe!SteamNetworkingSocketsLib::CSteamNetworkConnectionBase::BInitConnection(__int64 usecNow, int nOptions, const SteamNetworkingConfigValue_t * pOptions, char[1024] & errMsg) Line 987 C++
Chat.exe!SteamNetworkingSocketsLib::CSteamNetworkConnectionUDP::BInitConnect(const SteamNetworkingIPAddr & addressRemote, int nOptions, const SteamNetworkingConfigValue_t * pOptions, char[1024] & errMsg) Line 1199 C++
Chat.exe!SteamNetworkingSocketsLib::CSteamNetworkingSockets::ConnectByIPAddress(const SteamNetworkingIPAddr & address, int nOptions, const SteamNetworkingConfigValue_t * pOptions) Line 1135 C++
Chat.exe!ChatClient::Run(const SteamNetworkingIPAddr & serverAddr) Line 16 C++
Chat.exe!main(int argc, char * * argv) Line 80 C++
[External Code]
Код: Выделить всё
void ChatClient::Run(const SteamNetworkingIPAddr& serverAddr)
{
// Select instance to use. For now we'll always use the default.
m_Interface = SteamNetworkingSockets();
// Start connecting
char szAddr[SteamNetworkingIPAddr::k_cchMaxString];
serverAddr.ToString(szAddr, sizeof(szAddr), true);
Printf("Connecting to chat server at %s", szAddr);
SteamNetworkingConfigValue_t opt;
opt.SetPtr(k_ESteamNetworkingConfig_Callback_ConnectionStatusChanged, (void*)SteamNetConnectionStatusChangedCallback);
m_Connection = m_Interface->ConnectByIPAddress(serverAddr, 1, &opt);
if (m_Connection == k_HSteamNetConnection_Invalid)
FatalError("Failed to create connection");
while (!g_bQuit)
{
PollIncomingMessages();
PollConnectionStateChanges();
PollLocalUserInput();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
Запуск приложения в режиме сервера: server --port 27020 он работает нормально, поэтому проблема связана только с клиентским кодом.
Кроме того, исключение, с которым я сталкиваюсь, не всегда одно и то же. Иногда в тот же момент я получаю сообщение о нарушении доступа на запись. Иногда утверждение не удавалось в этой части файла xmemory:
Код: Выделить всё
_CONSTEXPR20 void deallocate(_Ty* const _Ptr, const size_t _Count) {
_STL_ASSERT(_Ptr != nullptr || _Count == 0, "null pointer cannot point to a block of non-zero size");
// no overflow check on the following multiply; we assume _Allocate did that check
_Deallocate(_Ptr, sizeof(_Ty) * _Count);
}
Воспроизводимый пример :
Я создал воспроизводимый пример (насколько я понял, что это такое)
Код: Выделить всё
#include "steam/steamnetworkingsockets.h"
int main() {
// Initialize the SteamNetworkingSockets library
SteamDatagramErrMsg errMsg;
GameNetworkingSockets_Init(nullptr, errMsg);
// Create the ISteamNetworkingSockets interface
ISteamNetworkingSockets* m_Interface = SteamNetworkingSockets();
// Set up the server address
SteamNetworkingIPAddr serverAddress;
serverAddress.Clear();
serverAddress.ParseString("127.0.0.1");
serverAddress.m_port = 27020;
// Display the server address
char szAddr[SteamNetworkingIPAddr::k_cchMaxString];
serverAddress.ToString(szAddr, sizeof(szAddr), true);
//Printf("Connecting to server at %s\n", szAddr);
// Attempt to connect
HSteamNetConnection m_Connection = m_Interface->ConnectByIPAddress(serverAddress, 0, nullptr);
m_Connection == k_HSteamNetConnection_Invalid;
// Cleanup
GameNetworkingSockets_Kill();
return 0;
}
Код: Выделить всё
Debug Assertion Failed!
Program: C:\Users\alexl\source\repos\Chat\x64\Debug\Chat.exe
File: D:\VisualStudio\VC\Tools\MSVC\14.36.32532\include\xmemory
Line: 944
Expression: null pointer cannot point to a block of non-zero size
For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.
(Press Retry to debug the application)
Код: Выделить всё
> Chat.exe!std::allocator::deallocate(char * const _Ptr, const unsigned __int64 _Count) Line 944 C++
Chat.exe!std::string::_Tidy_deallocate() Line 4877 C++
Chat.exe!std::string::~basic_string() Line 3159 C++
Chat.exe!SteamNetworkingSocketsLib::CSteamNetworkConnectionBase::SetLocalCertUnsigned() Line 1314 C++
Chat.exe!SteamNetworkingSocketsLib::CSteamNetworkConnectionBase::BThinkCryptoReady(__int64 usecNow) Line 1090 C++
Chat.exe!SteamNetworkingSocketsLib::CSteamNetworkConnectionBase::InitConnectionCrypto(__int64 usecNow) Line 1029 C++
Chat.exe!SteamNetworkingSocketsLib::CSteamNetworkConnectionBase::BInitConnection(__int64 usecNow, int nOptions, const SteamNetworkingConfigValue_t * pOptions, char[1024] & errMsg) Line 987 C++
Chat.exe!SteamNetworkingSocketsLib::CSteamNetworkConnectionUDP::BInitConnect(const SteamNetworkingIPAddr & addressRemote, int nOptions, const SteamNetworkingConfigValue_t * pOptions, char[1024] & errMsg) Line 1199 C++
Chat.exe!SteamNetworkingSocketsLib::CSteamNetworkingSockets::ConnectByIPAddress(const SteamNetworkingIPAddr & address, int nOptions, const SteamNetworkingConfigValue_t * pOptions) Line 1135 C++
Chat.exe!main() Line 140 C++
[External Code]
Вопрос очень длинный: все в порядке, или мне следует удалить все, кроме воспроизводимого примера?
Подробнее здесь: https://stackoverflow.com/questions/788 ... on-excepti
Мобильная версия