WinSock program in C, works only on local computer

房东的猫 提交于 2020-01-03 02:50:13

问题


I'm a newbie in Network Programming, started to learn how to use WinSock in C.

I don't have any knowledge in Networking right now.

Anyway, I've written the following code for Client and Server, using WinSock.

Server:

#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;

}

And this is the code for the Client:

#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;

}

Ok.

When I run both server and client on my comupter, and define IP (in the client code) to be my internal IP (I think, becuase it is the form of 192.168.x.x) it works fine.

When I define IP to be my external IP, it doesn't work on my computer (when I run both program in my computer). The connection failes.

In addition - When I'm trying to run the client on any other computer, it doesn't work (when IP is defined to be my internal or my external IP), the connection failes.

My questions are:

  1. Why when I run both server & client on my computer, it works just with my internal IP?

  2. What should I do in order that the client could be run on another computer and it will work?

  3. I know that maybe the answer contains terms like "internal/external IPs", "routers", maybe "firewall" or "port forwarding". Just remember I'm really a newbie in Networking and I don't have any knowledge about those terms, so please: I hope your explnations will be beginner-friendly. I want to start learning Networking, but my first step is to understand how to use Sockets, and I have a problem in the connetction with other computers.

If you have any articles/something like that in order to give me a better understanding of the problem, it could help too.

Thank you very much! :)


回答1:


This doesn't look like a coding problem, but a network configuration problem.

Let me try and rephrase what you're saying : Please correct me if I've misunderstood:-

  • You have an "internal" network (192.168.x.y).
  • You run the client on one PC on your internal network, and the server on another.
  • It all works so far.

But, you're also connected to the internet, via a different 'external' IP address - When your client tries to access the server via this address, it fails. (The exact error code from WSAGetLastError is useful here, please)

At this point, it's down to how you're connected to the net. Let's assume a typical home office scenario. You have broadband, with an ADSL router/modem giving you network connectivity. Now, while the router will have an 'external' IP address, PC's on your local network typically do NOT. So, if you try connecting to the 'external' IP, you're actually trying to talk to the router.

This is where Port forwarding comes into play. You need to configure the router to forward port 7777 to the correct IP address for your server on the internal network. You'll find a screen like this on your router somewhere.

You would enter port 7777 for both 'from' and 'to', enable TCP, and specify the LAN address of your server. The router will then forward incoming connections on port 7777 to the specified server.



来源:https://stackoverflow.com/questions/21111430/winsock-program-in-c-works-only-on-local-computer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!