这是Main.cpp直到错误发生的地方:
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nShowCmd)
{
if(SUCCEEDED(CoInitialize(NULL)))
{
{
Game game;
game.CreateRessources(hInst);
game.ShowMainScreen();
game.pWinsock->Initialize(game.Getm_hWnd());
game.Getm_hWnd返回私有HWND m_hWnd。
这是Game :: CreateRessources(HINSTANCE):
void Game::CreateRessources(HINSTANCE hInst)
{
m_hWnd=CreateWindowClass(hInst);
pMessageLog=CreateMessageLog();
pD2DResources=CreateD2DResources(m_hWnd);
pWinsock=CreateWinsock();
}
有CreateWinsock():
Winsock* CreateWinsock()
{
Winsock* pWinsock=new Winsock;
return pWinsock;
}
的Winsock :: Winsock的:
Winsock :: Winsock():Socket(NULL){}
最后,Winsock :: Initialize(HWND):
void Winsock::Initialize(HWND hwnd)
{
WSADATA wsaDat;
SendMessage(hwnd, LOG_ADD, NULL, (LPARAM)L"Initializing winsock... ");
int nResult = WSAStartup(MAKEWORD(2,2),&wsaDat);
if(nResult!=0)
{
MessageBox(NULL,"Winsock initialization failed","Critical error",MB_ICONERROR);
SendMessage(hwnd,WM_DESTROY,NULL,NULL);
}
SendMessage(hwnd, LOG_ADD, NULL, (LPARAM)L"Done!\nCreating a socket... ");
Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(Socket==INVALID_SOCKET)
{
MessageBox(NULL,"Socket Creation failed","Critical error",MB_ICONERROR);
SendMessage(hwnd,WM_DESTROY,NULL,NULL);
}
SendMessage(hwnd, LOG_ADD, NULL, (LPARAM)L"Done!\nRequesting Windows message-based notification of network events... ");
nResult=WSAAsyncSelect(Socket,hwnd,WM_SOCKET,(FD_CLOSE|FD_READ));
if(nResult)
{
if(WSAGetLastError()==WSAENOTSOCK)
MessageBox(hwnd,"WSAENOTSOCK Error!","Error",NULL);
MessageBox(NULL,"WSAAsyncSelect failed","Critical error",MB_ICONERROR);
SendMessage(hwnd,WM_DESTROY,NULL,NULL);
}
/* More code */
}
if行(WSAGetLastError()== WSAENOTSOCK)返回true。 WSAENOTSOCK意味着以下内容:
“非插槽上的套接字操作。 尝试对不是套接字的操作进行操作。套接字句柄参数未引用有效套接字,或者对于select,fd_set的成员无效。“
编辑:有我的Winsock课程:
class Winsock{
public:
Winsock();
void Initialize(HWND);
void ReceiveMsg();
private:
SOCKET Socket;
static const char* server;
static const int port;
};
据我所知,Socket是一个套接字,是一个有效的套接字。我怎么会收到那个错误?
答案 0 :(得分:2)
您正在将Socket
成员初始化为Winsock
构造函数中的错误值 - NULL
而不是INVALID_SOCKET
。它们的价值不一样。
无论WSAAsyncSelect()
成功还是失败,您都在呼叫socket()
。如果事情失败,您将显示错误消息,但是当您的代码失败时,您不会停止代码。您需要清理错误处理。
在旁注中,您需要使用DestroyWindow()
而不是手动发送WM_DESTROY
条消息。
请改为尝试:
class Winsock
{
public:
Winsock();
void Initialize(HWND);
void ReceiveMsg();
private:
SOCKET m_Socket;
...
};
Winsock::Winsock()
: m_Socket(INVALID_SOCKET)
{
}
void Winsock::Initialize(HWND hwnd)
{
SendMessage(hwnd, LOG_ADD, 0, (LPARAM)L"Initializing winsock... ");
WSADATA wsaDat = {0};
if (WSAStartup(MAKEWORD(2,2), &wsaDat) != 0)
{
SendMessage(hwnd, LOG_ADD, 0, (LPARAM)L"Winsock initialization failed");
return;
}
SendMessage(hwnd, LOG_ADD, 0, (LPARAM)L"Done!\nCreating a socket... ");
m_Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (m_Socket == INVALID_SOCKET)
{
SendMessage(hwnd, LOG_ADD, 0, (LPARAM)L"Socket Creation failed");
return;
}
SendMessage(hwnd, LOG_ADD, 0, (LPARAM)L"Done!\nRequesting Windows message-based notification of network events... ");
if (WSAAsyncSelect(m_Socket, hwnd, WM_SOCKET, FD_CLOSE|FD_READ) != 0)
{
SendMessage(hwnd, LOG_ADD, 0, (LPARAM)L"WSAAsyncSelect failed");
return;
}
/* More code */
}
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nShowCmd)
{
if(SUCCEEDED(CoInitialize(NULL)))
{
Game game;
game.CreateResources(hInst);
game.ShowMainScreen();
...
}
}
void Game::CreateResources(HINSTANCE hInst)
{
m_hWnd = CreateWindowClass(hInst);
pMessageLog = CreateMessageLog();
pD2DResources = CreateD2DResources(m_hWnd);
pWinsock = CreateWinsock();
pWinsock->Initialize(m_hWnd);
}