简体   繁体   English

Winsock服务器无法连接

[英]Winsock server unable to connect

I've written (rather, copied from a tutorial :P) a winsock server, in c++ which waits for the client to send a message and then closes. 我已经用c ++编写了(而是从教程:P复制而来)一个Winsock服务器,它等待客户端发送消息然后关闭。 The server works when both the client and the server are on my PC, but when i move the client to another computer, it fails. 当客户端和服务器都在我的PC上时,服务器可以工作,但是当我将客户端移动到另一台计算机时,它会失败。 I think it's a problem with my ip adress but 192.168.254.4 is what i get when i type ipconfig \\all in command prompt. 我认为这是我的IP地址存在的问题,但是在命令提示符下键入ipconfig \\all时得到的是192.168.254.4。

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);
}

Client 客户

//******************************************************************************
//
// 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);
}

If you're running the unmodified client code on a different machine, it's probably still trying to connect to a server on "localhost", which is not what you want. 如果您在另一台计算机上运行未修改的客户端代码,则可能仍在尝试连接到“ localhost”上的服务器,这不是您想要的。 [ Edit : OP has updated his client code and is now using an IP address.] [ 编辑 :OP更新了他的客户代码,现在正在使用IP地址。]

In a typical home/office LAN setup, you probably want to use IP addresses rather than hostnames to specify the server to use. 在典型的家庭/办公室LAN设置中,您可能想使用IP地址而不是主机名来指定要使用的服务器。 You may also need to check that the network port you've specified is not blocked by software firewalls on the client or server machines, or by a hardware firewall or router between the server and client. 您可能还需要检查所指定的网络端口是否未被客户端或服务器计算机上的软件防火墙或服务器与客户端之间的硬件防火墙或路由器所阻止。

One way to debug such a problem is to use a tool like Wireshark to monitor the network traffic between the client and server. 调试此问题的一种方法是使用Wireshark之类的工具来监视客户端和服务器之间的网络流量。 Are packets leaving the client's machine when it attempts to establish a connection? 尝试建立连接时,数据包是否离开客户端计算机? Are the requests seen by the server's machine? 服务器的计算机是否看到了请求? Is one side or the other prematurely closing the connection? 一侧或另一侧是否过早关闭了连接? Remember that firewalls can block outgoing traffic as well as incoming traffic... 请记住,防火墙可以阻止传出流量和传入流量...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM