c ++ - Winsock server ude af stand til at forbinde

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har skrevet (snarere kopieret fra en vejledning: P) en winsock-server, i c ++, som venter på, at klienten sender en besked og lukker derefter. Serveren virker, når både klienten og serveren er på min pc, men når Jeg flytter klienten til en anden computer, det fejler.
Jeg tror, ​​at det er et problem med min ip-adresse, men 192.168.254.4 er det, jeg får, når jeg skriver ipconfig all i kommandoprompten.


server



//******************************************************************************
//
// Main.cpp
//
// Main source file of the Listener program, which employs blocking sockets and
// Winsock to listen for outside connections.
//
// If you are not using the included Dev-C++ project file, be sure to link with
// the Winsock library, usually wsock32.lib or something similarly named.
//
// Author:  Johnnie Rose, Jr. (johnnie2@hal-pc.org)
// Date:  1/08/03 (version 2)
// Website:  http://www.hal-pc.org/~johnnie2/winsock.html
//
//******************************************************************************

#include <windows.h>
#include <winsock2.h>
#include <stdio.h>
#include <iostream>
#define NETWORK\_ERROR -1
#define NETWORK\_OK     0

void ReportError(int, const char *);
using namespace std;

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmd, int nShow) {
   WORD sockVersion;
   WSADATA wsaData;
   int nret;

   sockVersion = MAKEWORD(2, 2);              // We'd like Winsock version 1.1

   // We begin by initializing Winsock
   WSAStartup(sockVersion, &wsaData);

   // Next, create the listening socket
   SOCKET listeningSocket;

   listeningSocket = socket(AF\_INET,          // Go over TCP/IP
                            SOCK\_STREAM,      // This is a stream-oriented socket
                            IPPROTO\_TCP);     // Use TCP rather than UDP

   if (listeningSocket == INVALID\_SOCKET) {
      nret = WSAGetLastError();               // Get a more detailed error
      ReportError(nret, "socket()");          // Report the error with our custom function

      WSACleanup();                           // Shutdown Winsock
      return NETWORK\_ERROR;                   // Return an error value
   }

   // Use a SOCKADDR\_IN struct to fill in address information
   SOCKADDR\_IN serverInfo;

   serverInfo.sin\_family = AF\_INET;
   serverInfo.sin\_addr.s\_addr = INADDR\_ANY;   // Since this socket is listening for
                                              // connections, any local address will do
   serverInfo.sin\_port = htons(8888);         // Convert integer 8888 to network-byte order
                                              // and insert into the port field

   // Bind the socket to our local server address
   nret = bind(listeningSocket, (LPSOCKADDR)&serverInfo, sizeof(struct sockaddr));

   if (nret == SOCKET\_ERROR) {
      nret = WSAGetLastError();
      ReportError(nret, "bind()");

      WSACleanup();
      return NETWORK\_ERROR;
   }

   // Make the socket listen
   nret = listen(listeningSocket, 10);        // Up to 10 connections may wait at any
                                              // one time to be accept()'ed

   if (nret == SOCKET\_ERROR) {
      nret = WSAGetLastError();
      ReportError(nret, "listen()");

      WSACleanup();
      return NETWORK\_ERROR;
   }

   // Wait for a client
   cout << "Waiting for client" << endl;
   SOCKET theClient;

   theClient = accept(listeningSocket,
                      NULL,                   // Address of a sockaddr structure (see explanation below)
                      NULL);                  // Address of a variable containing size of sockaddr struct

   if (theClient == INVALID\_SOCKET) {
      nret = WSAGetLastError();
      ReportError(nret, "accept()");

      WSACleanup();
      return NETWORK\_ERROR;
   }
   char Buffer[256];
       recv(theClient, Buffer, 256, 0);
       printf(Buffer, 2);
   // Send and receive from the client, and finally,
   closesocket(theClient);
   closesocket(listeningSocket);


   // Shutdown Winsock
   WSACleanup();
   system("PAUSE");
   return NETWORK\_OK;
}


void ReportError(int errorCode, const char *whichFunc) {
   char errorMsg[92];                         // Declare a buffer to hold
                                              // the generated error message

   ZeroMemory(errorMsg, 92);                  // Automatically NULL-terminate the string

   // The following line copies the phrase, whichFunc string, and integer errorCode into the buffer
   sprintf(errorMsg, "Call to \%s returned error \%d!", (char *)whichFunc, errorCode);

   MessageBox(NULL, errorMsg, "socketIndication", MB\_OK);
}


Klient



//******************************************************************************
//
// Main.cpp
//
// Main source file of the Connector program, which employs blocking sockets and
// Winsock to connect to an outside server.
//
// If you are not using the included Dev-C++ project file, be sure to link with
// the Winsock library, usually wsock32.lib or something similarly named.
//
// Author:  Johnnie Rose, Jr. (johnnie2@hal-pc.org)
// Date:  1/08/03 (version 2)
// Website:  http://www.hal-pc.org/~johnnie2/winsock.html
//
//******************************************************************************

#include <windows.h>
#include <winsock2.h>
#include <stdio.h>
#include <iostream>
#define NETWORK\_ERROR -1
#define NETWORK\_OK     0

void ReportError(int, const char *);
using namespace std;
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmd, int nShow) {
   WORD sockVersion;
   WSADATA wsaData;
   int nret;
   cout <<"Loading WinSock" << endl;
   sockVersion = MAKEWORD(2, 2);

   // Initialize Winsock as before
   WSAStartup(sockVersion, &wsaData);

   // Store information about the server
   LPHOSTENT hostEntry;
   in\_addr iaHost;
   iaHost.s\_addr = inet\_addr("192.168.254.4");
   hostEntry = gethostbyaddr((const char *)&iaHost, sizeof(struct in\_addr), AF\_INET);     // Specifying the server by its name;
                                                   // another option is gethostbyaddr()
   if (!hostEntry) {
      nret = WSAGetLastError();
      ReportError(nret, "gethostbyaddr()");         // Report the error as before

      WSACleanup();
      return NETWORK\_ERROR;
   }

   // Create the socket
   cout <<"Creating Socket";
   SOCKET theSocket;

   theSocket = socket(AF\_INET,                      // Go over TCP/IP
                      SOCK\_STREAM,                  // This is a stream-oriented socket
                      IPPROTO\_TCP);                 // Use TCP rather than UDP

   if (theSocket == INVALID\_SOCKET) {
      nret = WSAGetLastError();
      ReportError(nret, "socket()");

      WSACleanup();
      return NETWORK\_ERROR;
   }

   // Fill a SOCKADDR\_IN struct with address information
   SOCKADDR\_IN serverInfo;

   serverInfo.sin\_family = AF\_INET;
   serverInfo.sin\_addr = *((LPIN\_ADDR)*hostEntry->h\_addr\_list);   // See the explanation in the tutorial
   serverInfo.sin\_port = htons(8888);                 // Change to network-byte order and
                                                    // insert into port field
    cout << "Connecting to server" << endl;
   // Connect to the server
   nret = connect(theSocket,
                  (LPSOCKADDR)&serverInfo,
                  sizeof(struct sockaddr));

   if (nret == SOCKET\_ERROR) {
      nret = WSAGetLastError();
      ReportError(nret, "connect()");

      WSACleanup();
      return NETWORK\_ERROR;
   }

   // Successfully connected!
   char* Buffer;
   send(theSocket, "A", 1, 0);
   recv(theSocket, Buffer, 256,0);
   printf(Buffer,256);
   // Send/receive, then cleanup:
   closesocket(theSocket);
   WSACleanup();

   system("PAUSE");
   return 0;
}


void ReportError(int errorCode, const char *whichFunc) {
   char errorMsg[92];                               // Declare a buffer to hold
                                                    // the generated error message

   ZeroMemory(errorMsg, 92);                        // Automatically NULL-terminate the string

   // The following line copies the phrase, whichFunc string, and integer errorCode into the buffer
   sprintf(errorMsg, "Call to \%s returned error \%d!", (char *)whichFunc, errorCode);

   MessageBox(NULL, errorMsg, "socketIndication", MB\_OK);
}

Bedste reference


Hvis du kører den umodificerede klientkode på en anden maskine, forsøger den sandsynligvis stadig at oprette forbindelse til en server på 'localhost', hvilket ikke er det, du ønsker. [[ Rediger : OP har opdateret sin klientkode og bruger nu en IP-adresse.]]


I et typisk hjem/kontor LAN opsætning vil du sandsynligvis bruge IP-adresser i stedet for
værtsnavne til at angive den server, der skal bruges. Du skal muligvis også kontrollere, at netværket
Den port, du har angivet, er ikke blokeret af software firewalls på klienten eller serveren
maskiner eller en hardware firewall eller router mellem serveren og klienten.


En måde at fejle et sådant problem på er at bruge et værktøj som Wireshark til at overvåge
netværkstrafikken mellem klienten og serveren. Er pakkerne efterladt klientens maskine, når den forsøger at etablere en forbindelse? Behandles anmodningerne fra serverens maskine? Er den ene side eller den anden for tidligt lukker forbindelsen? Husk at firewalls kan blokere udgående trafik samt indgående trafik ... [4]