我正在尝试从另一台计算机公开连接到我的电脑,它会从connect函数返回10060
错误代码。
当我bind
来自本地计算机的inet_addr("127.0.0.1")
服务器时
并与客户联系,以确保其有效。
我尝试使用下面相同的客户端代码连接服务器的公共IP,返回10060
任何人都可以帮忙吗?
服务器
#include<winsock2.h>
int main(){
WSADATA ws;
SOCKET s, newSocket;
struct sockaddr_in server, client;
int c;
if(WSAStartup(MAKEWORD(2,2), &ws) != 0){
puts("error wsastartup");
printf("wsa error at %d", GetLastError());
}
if((s=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET){
printf("socket error at %d", GetLastError());
}
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_port = htons(8888);
server.sin_family = AF_INET;
if(bind(s, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR){
printf("socket error at %d", GetLastError());
}else{
puts("bind done");
}
listen(s, 3);
puts("Waiting for incoming connections");
c = sizeof(struct sockaddr_in);
char *message = "hello client i got ur message";
while((newSocket = accept(s, (struct sockaddr*) &client, &c)) != INVALID_SOCKET){
puts("connection accepted");
send(newSocket, message, strlen(message), 0);
}
if(newSocket == INVALID_SOCKET){
printf("accept failed iwth the code %d", GetLastError());
return 1;
}
getchar();
closesocket(s);
WSACleanup();
return 0;
}
这是客户
#include <winsock2.h>
int main(){
WSADATA ws;
SOCKET s;
struct sockaddr_in server;
char *message = "hello this is a message";
if(WSAStartup(MAKEWORD(2,2 ), &ws) != 0){
printf("wsa error at %d", GetLastError());
}else{
puts("wsa done");
}
if((s = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET){
printf("invalid socket at %d", GetLastError());
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_port = htons(8888);
if(connect(s, (struct sockaddr*)&server, sizeof(server)) < 0){
printf("connection err %d", GetLastError());
}else{
puts("connected");
}
return 0;
}
答案 0 :(得分:15)
问题在于您的服务器。您将其绑定到127.0.0.1
。这意味着您的服务器将仅绑定到环回接口,因此只有与服务器在同一台计算机上运行的客户端才能使用此相同的接口连接到服务器。
如果您希望服务器从公共网络接口接受客户端,则必须绑定到该接口的IP:
server.sin_addr.s_addr = inet_addr("<IP belonging to the public interface>");
或者,您可以将服务器绑定到所有可用的网络接口:
server.sin_addr.s_addr = inet_addr("0.0.0.0");
或者:
server.sin_addr.s_addr = INADDR_ANY;
请注意,您只能绑定到属于运行服务器的计算机的IP。如果客户端尝试连接的公共IP属于NAT /路由器,则必须将服务器绑定到连接到NAT /路由器的本地LAN IP,然后在NAT /路由器上设置端口转发以转发从NAT /路由器的公共IP上的开放端口到服务器LAN IP上的侦听端口的数据包。如果NAT /路由器支持uPNP,您的服务器可以可编程地设置端口转发。否则,NAT /路由器的管理员必须手动设置转发。