winsock 无法连接到本地主机
winsock fails to connect to localhost
对于我的项目,我无法调试程序,所以我不能确定为什么会出现此错误。
我的托管在 c# 上的服务器无法连接到本地主机上的服务器。
它没有向我的服务器发回“连接”信号,而是永远连接不上,我认为代码写得很好,我看不到任何错误,也许我在某处犯了一个粗心的错误
此外,我必须使用 gethostbyname 而不是 getaddrinfo
winsock 命名空间:
SOCKET WinSock::ConnectToServer(PCHAR IP, USHORT Port)
{
WSADATA WSA;
if (WSAStartup(MAKEWORD(2, 0), &WSA))
{
SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s != SOCKET_ERROR)
{
hostent *Host = gethostbyname(IP);
if (Host != ERROR)
{
SOCKADDR_IN Addr;
Addr.sin_family = AF_INET;
Addr.sin_port = htons(Port);
Addr.sin_addr.s_addr = NULL;
if (bind(s, PSOCKADDR(&Addr), sizeof(Addr)) > 0)
{
return s;
}
}
}
}
return FALSE;
}
BOOL WinSock::SendData(SOCKET s, PBYTE Packet)
{
DWORD PacketSize = lstrlenA(PCHAR(Packet));
if (send(s, PCHAR(&PacketSize), 8, 0) > NULL)
{
if (send(s, PCHAR(Packet), PacketSize, 0) > NULL)
{
return TRUE;
}
}
return FALSE;
}
主要方法:
int main()
{
char key = 1;
SOCKET S = WinSock::ConnectToServer(0, 55480);
while(true)
{
WinSock:SendData(S, (PBYTE)key);
}
}
if (bind(s, PSOCKADDR(&Addr), sizeof(Addr)) > 0)
这段代码的描述是它应该连接到服务器。但问题是 bind()
没有连接到任何服务器。它只将套接字链接到本地端口。这就是侦听套接字的服务器所做的。这大概是服务器已经打开的同一个端口,因此 bind()
失败。如果服务器没有监听,bind()
将会成功,具有讽刺意味的是。但无论如何,它不会连接到任何东西。
您想使用 connect()
而不是 bind()
。
此外,我必须注意,如果此函数首先创建了一个套接字,但随后由于此原因或任何其他原因无法建立连接,它将 return 一个错误指示但无法关闭套接字,从而泄漏套接字描述符。你也必须修复这个错误。
您实际上并没有与服务器建立连接。您正在调用 bind()
将客户端套接字绑定到 local 端口 55480,但这不会创建连接。您需要改为调用 connect()
将客户端套接字连接到 远程 端口 55480。
此外,您的 SendData()
编码错误。它告诉 send()
为 PacketSize
发送 8 个字节,但是 DWORD
的大小只有 4 个字节。并且 send()
不会 return NULL
失败。并且 send()
不保证发送所有请求的字节,所以你需要在循环中调用它。并且习惯上以网络字节顺序(big endian)发送多字节整数。
此外,您已将 SendData()
编码为期望以 null 结尾的 C 样式字符串,但这并不是您的 main()
实际传递给它的内容。
试试像这样的东西:
bool WinSock::Init()
{
WSADATA WSA;
return (WSAStartup(MAKEWORD(2, 0), &WSA) == 0);
}
bool WinSock::Cleanup()
{
return (WSACleanup() == 0);
}
SOCKET WinSock::ConnectToServer(const char *IP, unsigned short Port)
{
hostent *Host = gethostbyname(IP);
if ((Host != NULL) && (Host->h_addrtype == AF_INET)
{
SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s != INVALID_SOCKET)
{
SOCKADDR_IN Addr = {};
Addr.sin_family = AF_INET;
Addr.sin_port = htons(Port);
Addr.sin_addr.s_addr = * (u_long*) Host->h_addr;
if (connect(s, PSOCKADDR(&Addr), sizeof(Addr)) != SOCKET_ERROR)
{
return s;
}
closesocket(s);
}
}
return INVALID_SOCKET;
}
bool WinSock::Close(SOCKET s)
{
return (closesocket(s) == 0);
}
bool WinSock::SendData(SOCKET s, const void* Data, DWORD DataSize)
{
const char *ptr = (const char*) Data;
while (DataSize > 0)
{
int numSent = send(s, ptr, DataSize, 0);
if (numSent == SOCKET_ERROR) return false;
ptr += numSent;
DataSize -= numSent;
}
return true;
}
bool WinSock::SendData(SOCKET s, const char *Packet)
{
DWORD PacketSize = lstrlenA(Packet);
DWORD tmp = htonl(PacketSize);
if (!SendData(s, &tmp, sizeof(tmp)) return false;
return SendData(s, Packet, PacketSize);
}
int main()
{
if (WinSock::Init())
{
const char *key = "1";
SOCKET S = WinSock::ConnectToServer(NULL, 55480);
if (s != INVALID_SOCKET)
{
while (true)
{
WinSock:SendData(S, key);
}
WinSock::Close(s);
}
WinSock::Cleanup();
}
return 0;
}
对于我的项目,我无法调试程序,所以我不能确定为什么会出现此错误。
我的托管在 c# 上的服务器无法连接到本地主机上的服务器。
它没有向我的服务器发回“连接”信号,而是永远连接不上,我认为代码写得很好,我看不到任何错误,也许我在某处犯了一个粗心的错误
此外,我必须使用 gethostbyname 而不是 getaddrinfo
winsock 命名空间:
SOCKET WinSock::ConnectToServer(PCHAR IP, USHORT Port)
{
WSADATA WSA;
if (WSAStartup(MAKEWORD(2, 0), &WSA))
{
SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s != SOCKET_ERROR)
{
hostent *Host = gethostbyname(IP);
if (Host != ERROR)
{
SOCKADDR_IN Addr;
Addr.sin_family = AF_INET;
Addr.sin_port = htons(Port);
Addr.sin_addr.s_addr = NULL;
if (bind(s, PSOCKADDR(&Addr), sizeof(Addr)) > 0)
{
return s;
}
}
}
}
return FALSE;
}
BOOL WinSock::SendData(SOCKET s, PBYTE Packet)
{
DWORD PacketSize = lstrlenA(PCHAR(Packet));
if (send(s, PCHAR(&PacketSize), 8, 0) > NULL)
{
if (send(s, PCHAR(Packet), PacketSize, 0) > NULL)
{
return TRUE;
}
}
return FALSE;
}
主要方法:
int main()
{
char key = 1;
SOCKET S = WinSock::ConnectToServer(0, 55480);
while(true)
{
WinSock:SendData(S, (PBYTE)key);
}
}
if (bind(s, PSOCKADDR(&Addr), sizeof(Addr)) > 0)
这段代码的描述是它应该连接到服务器。但问题是 bind()
没有连接到任何服务器。它只将套接字链接到本地端口。这就是侦听套接字的服务器所做的。这大概是服务器已经打开的同一个端口,因此 bind()
失败。如果服务器没有监听,bind()
将会成功,具有讽刺意味的是。但无论如何,它不会连接到任何东西。
您想使用 connect()
而不是 bind()
。
此外,我必须注意,如果此函数首先创建了一个套接字,但随后由于此原因或任何其他原因无法建立连接,它将 return 一个错误指示但无法关闭套接字,从而泄漏套接字描述符。你也必须修复这个错误。
您实际上并没有与服务器建立连接。您正在调用 bind()
将客户端套接字绑定到 local 端口 55480,但这不会创建连接。您需要改为调用 connect()
将客户端套接字连接到 远程 端口 55480。
此外,您的 SendData()
编码错误。它告诉 send()
为 PacketSize
发送 8 个字节,但是 DWORD
的大小只有 4 个字节。并且 send()
不会 return NULL
失败。并且 send()
不保证发送所有请求的字节,所以你需要在循环中调用它。并且习惯上以网络字节顺序(big endian)发送多字节整数。
此外,您已将 SendData()
编码为期望以 null 结尾的 C 样式字符串,但这并不是您的 main()
实际传递给它的内容。
试试像这样的东西:
bool WinSock::Init()
{
WSADATA WSA;
return (WSAStartup(MAKEWORD(2, 0), &WSA) == 0);
}
bool WinSock::Cleanup()
{
return (WSACleanup() == 0);
}
SOCKET WinSock::ConnectToServer(const char *IP, unsigned short Port)
{
hostent *Host = gethostbyname(IP);
if ((Host != NULL) && (Host->h_addrtype == AF_INET)
{
SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s != INVALID_SOCKET)
{
SOCKADDR_IN Addr = {};
Addr.sin_family = AF_INET;
Addr.sin_port = htons(Port);
Addr.sin_addr.s_addr = * (u_long*) Host->h_addr;
if (connect(s, PSOCKADDR(&Addr), sizeof(Addr)) != SOCKET_ERROR)
{
return s;
}
closesocket(s);
}
}
return INVALID_SOCKET;
}
bool WinSock::Close(SOCKET s)
{
return (closesocket(s) == 0);
}
bool WinSock::SendData(SOCKET s, const void* Data, DWORD DataSize)
{
const char *ptr = (const char*) Data;
while (DataSize > 0)
{
int numSent = send(s, ptr, DataSize, 0);
if (numSent == SOCKET_ERROR) return false;
ptr += numSent;
DataSize -= numSent;
}
return true;
}
bool WinSock::SendData(SOCKET s, const char *Packet)
{
DWORD PacketSize = lstrlenA(Packet);
DWORD tmp = htonl(PacketSize);
if (!SendData(s, &tmp, sizeof(tmp)) return false;
return SendData(s, Packet, PacketSize);
}
int main()
{
if (WinSock::Init())
{
const char *key = "1";
SOCKET S = WinSock::ConnectToServer(NULL, 55480);
if (s != INVALID_SOCKET)
{
while (true)
{
WinSock:SendData(S, key);
}
WinSock::Close(s);
}
WinSock::Cleanup();
}
return 0;
}