2014-01-14 23 views
1

上我在网络编程新手,开始学习如何使用的WinSock在C.WinSock程序,只能在本地计算机

我没有在现在网络的任何知识。

无论如何,我已经使用WinSock为客户端和服务器编写了以下代码。

服务器:

#include <stdio.h> 
#include <stdlib.h> 
#include <winsock2.h> 
#include <ws2tcpip.h> 

#define MY_ERROR 1 
#define PORT 7777 
#define MAX_NUM_CLIENTS 1 /* I don't know how to thread right now. */ 
#define MAX_CLIENT_MSG_LEN 1000 
int main() 
{ 
WSADATA wsa; 
SOCKET mySocket, acceptSocket; 
struct sockaddr_in server, client; 
int sockAddrInLength = sizeof(struct sockaddr_in); 
char clientMessage[MAX_CLIENT_MSG_LEN]; 
int clientMessageLength; 
char* message; 

int running = 1; 

if(WSAStartup(MAKEWORD(2,2), &wsa) != 0) 
{ 
    fprintf(stderr, "WSAStartup failed.\n"); 
    return MY_ERROR; 
} 
printf("WSAStartup succeded.\n"); 

mySocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
if (mySocket == INVALID_SOCKET) 
{ 
    fprintf(stderr, "Socket creation failed.\n"); 
    return MY_ERROR; 
} 
printf("Socket creation succeeded.\n"); 

server.sin_addr.s_addr = INADDR_ANY; 
server.sin_family = AF_INET; 
server.sin_port = htons(PORT); 

if (bind(mySocket, (struct sockaddr*) &server, sizeof server) == SOCKET_ERROR) 
{ 
    fprintf(stderr, "Binding socket on port %d failed.\n", PORT); 
    return MY_ERROR; 
} 
printf("Binding socket on port %d successfully.\n", PORT); 

while (running) 
{ 
     listen(mySocket, MAX_NUM_CLIENTS); 
     printf("Waiting for a connection...\n"); 

     acceptSocket = accept(mySocket, (struct sockaddr*) &client, &sockAddrInLength); 
     if (acceptSocket == INVALID_SOCKET) 
     { 
      fprintf(stderr, "Accept failed.\n"); 
      return MY_ERROR; 
     } 
     printf("Accept succeeded.\n"); 

     if ((clientMessageLength = recv(acceptSocket, clientMessage, sizeof clientMessage, 0)) == SOCKET_ERROR) 
     { 
      fprintf(stderr, "Recv failed.\n"); 
      return MY_ERROR; 
     } 
     printf("Recv succeeded.\n"); 

     printf("Data:\n"); 
     clientMessage[clientMessageLength] = NULL; /* Null terminator */ 
     printf("Client: %s\n", clientMessage); 

     message = "Hello client, I'm the server. Bye bye. :-)\n"; 
     if (send(acceptSocket, message, strlen(message), 0) < 0) 
     { 
      fprintf(stderr, "Send failed.\n"); 
      return MY_ERROR; 
     } 
     printf("Send succeded.\n"); 
} 
closesocket(mySocket); 
WSACleanup(); 
getchar(); 
return 0; 

} 

这是客户端的代码:

#include <stdio.h> 
#include <stdlib.h> 
#include <winsock2.h> 
#include <ws2tcpip.h> 


#define IP /* My IP */ 
#define MY_ERROR 1 
#define PORT 7777 
#define MAX_SERVER_MSG_LEN 1000 

int main() 
{ 
WSADATA wsa; 
SOCKET mySocket; 
struct sockaddr_in server; 
char* message; 
char serverMessage[MAX_SERVER_MSG_LEN]; 
int serverMessageLength; 

if(WSAStartup(MAKEWORD(2,2), &wsa) != 0) 
{ 
    fprintf(stderr, "WSAStartup failed.\n"); 
    getchar(); 
    return MY_ERROR; 
} 
printf("WSASucceeded.\n"); 

mySocket = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP); 

if (mySocket == INVALID_SOCKET) 
{ 
    fprintf(stderr, "Socket creation failed.\n"); 
    getchar(); 
    return MY_ERROR; 
} 

server.sin_addr.s_addr = inet_addr(IP); 
server.sin_family = AF_INET; 
server.sin_port = htons(PORT); 

if (connect(mySocket, (struct sockaddr*) &server, sizeof server) < 0) 
{ 
    fprintf(stderr, "Connection failed. error: %s\n",WSAGetLastError()); 
    getchar(); 
    return MY_ERROR; 
} 
printf("Connection established.\n"); 

message = "Hello server, I'm the sweet client. :-)\n"; 
if (send(mySocket, message, strlen(message), 0) < 0) 
{ 
    fprintf(stderr, "Sending failed.\n"); 
    return MY_ERROR; 
} 
printf("Sending succeeded.\n"); 

if ((serverMessageLength = recv(mySocket, serverMessage, sizeof serverMessage, 0)) == SOCKET_ERROR) 
{ 
    fprintf(stderr, "Recv failed.\n"); 
    return MY_ERROR; 
} 
printf("Recv succeeded.\n"); 

printf("Data:\n"); 
serverMessage[serverMessageLength] = NULL; 
printf("Server: %s", serverMessage); 

closesocket(mySocket); 
getchar(); 
return 0; 

} 

确定。

当我在我的comupter上运行服务器和客户端,并将IP(在客户端代码中)定义为我的内部IP(我认为,因为它是192.168.x.x的形式),它工作正常。

当我将IP定义为我的外部IP时,它无法在我的计算机上运行(当我在计算机上运行这两个程序时)。连接失败。

此外 - 当我试图在任何其他计算机上运行客户端时,它不起作用(当IP被定义为我的内部IP或我的外部IP时),连接失败。

我的问题是:

  1. 为什么当我在我的电脑上同时运行服务器端&,它只是我的内部IP?

  2. 我应该怎么做才能使客户端可以在另一台计算机上运行,​​并且它会工作?

  3. 我知道答案可能包含“内部/外部IP”,“路由器”,也许“防火墙”或“端口转发”等术语。 只要记住我是网络新手,我对这些条款没有任何了解,所以请:我希望你的探索会对初学者友好。 我想开始学习网络,但我的第一步是了解如何使用套接字,并且我在与其他计算机的连接中遇到问题。

如果您有任何文章/类似的东西,以便让我更好地了解问题,它也可以帮助。

非常感谢! :)

+0

“这不起作用”不是一个有帮助的问题描述。 –

+0

当您尝试从另一台计算机连接到服务器时,您可以发布您收到的错误吗? –

+0

@DavidSchwartz对不起,但我只是没有足够的网络知识,以更好地解释它。连接失败(我在客户端输入'if'语句并打印'连接失败' – Programmer

回答

2

这看起来不像编码问题,而是网络配置问题。

,让我试着改一下你在说什么:请纠正我,如果我误解: -

  • 你有一个“内部”网络(192.168.x.y)。
  • 您在内部网络上的一台PC上运行客户端,在另一台PC上运行该服务器。
  • 这一切都工作到目前为止。

但是,你也连接到互联网,通过不同的“外部” IP地址 - 当你的客户端尝试通过这个地址来访问服务器,它失败。 (从WSAGetLastError确切的错误代码在这里是有用的,请)

在这一点上,这取决于你如何连接到网络。我们假设一个典型的家庭办公场景。你有宽带,用ADSL路由器/调制解调器为你提供网络连接。现在,虽然路由器将具有“外部”IP地址,但本地网络上的PC通常不会。因此,如果您尝试连接到“外部”IP,您实际上正在尝试与路由器通话。

这是Port forwarding发挥作用。您需要配置路由器将内部网络上的服务器的端口7777转发到正确的IP地址。你会在你的路由器上找到这样的屏幕。

enter image description here

您可以输入端口7777两个“从”和“到”,启用TCP,并指定服务器的局域网地址。路由器然后将端口7777上的传入连接转发到指定的服务器。

+0

非常感谢!它的工作:)正是我正在寻找的答案。 – Programmer

相关问题