我如何在这个程序中使用我的IP地址?如果我把我的地址改为127.0.0.1,服务器不响应

时间:2010-12-12 11:47:40

标签: c++

我的问题在于:

server.sin_addr.s_addr = inet_addr("127.0.0.1");

在客户端路径中。如果我把我的地址改为127.0.0.1,那么服务器就没有响应。 我需要通过wireshark数据包嗅探器来查看此程序中的流量...

 //Client   

#define TIME_PORT 27015
#define NUM_OF_REQUEST 5
#define SIZE 10
int getRequestFromUser();
float calculateAverage(int* arr);

void main() 
{
 //allocating memory to get the needed information from user 


    // Initialize Winsock (Windows Sockets).

 WSAData wsaData; 
 if (NO_ERROR != WSAStartup(MAKEWORD(2,2), &wsaData))
 {
  cout<<"Time Client: Error at WSAStartup()\n";
 }

 // Client side:
 // Create a socket and connect to an internet address.

    SOCKET connSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
 if (INVALID_SOCKET == connSocket)
 {
        cout<<"Time Client: Error at socket(): "<<WSAGetLastError()<<endl;
        WSACleanup();
        return;
 }

 // For a client to communicate on a network, it must connect to a server.

 // Need to assemble the required data for connection in sockaddr structure.

    // Create a sockaddr_in object called server. 
 sockaddr_in server;
    server.sin_family = AF_INET; 
 server.sin_addr.s_addr = inet_addr("127.0.0.1");
 server.sin_port = htons(TIME_PORT);

    // Send and receive data.

    int bytesSent = 0;
    int bytesRecv = 0;
 char sendBuff[255];
 char recvBuff[255];
 int requestFromUser = -1;

 while(requestFromUser != 0){

 requestFromUser=getRequestFromUser();
 // for mmeasure RTT/Delay
 float average=0;
 bool findDelay=false;
 bool findRTT=false;

 //matching between numbers and what they mean:
 switch (requestFromUser)
 {
 case 1:
  strcpy(sendBuff,"GetTime");
  break;
 case 2:
  strcpy(sendBuff,"GetTimeWithoutYear");
  break;
 case 3:
  strcpy(sendBuff,"GetTimeSinceEpoch");
  break;
 case 4:
  {
  strcpy(sendBuff,"GetClientToServerDelayEstimation");
  findDelay=true;
  break;
  }
 case 5:
  {
  strcpy(sendBuff,"MeasureRTT");
  findRTT=true;
  break;
  }
 case 6:
  {
   strcpy(sendBuff, "GetDayAndMonth");
   break;
  }
 default:
  ;//don't exist
 }

 // Asks the server what's the currnet time.
 // The send function sends data on a connected socket.
 // The buffer to be sent and its size are needed.
 // The fourth argument is an idicator specifying the way in which the call is made (0 for default).
 // The two last arguments hold the details of the server to communicate with. 
 // NOTE: the last argument should always be the actual size of the client's data-structure (i.e. sizeof(sockaddr)).

 if (findDelay)
 {
  int i;
  long int arrTimeR[SIZE];
  int arrTime[SIZE];
  time_t  arrTimeSend[SIZE];
  //Start sending the request
  strcpy(sendBuff,"GetTimeSinceEpoch");
  for (i=0; i<SIZE; i++)
  {

   //sending request
   bytesSent = sendto(connSocket, sendBuff, (int)strlen(sendBuff), 0, (const sockaddr *)&server, sizeof(server));
   arrTimeSend[i]= time (NULL);
   if (SOCKET_ERROR == bytesSent)
   {
    cout<<"Time Client: Error at sendto(): "<<WSAGetLastError()<<endl;
    closesocket(connSocket);
    WSACleanup();
    return;
   }

   //recieving data
   bytesRecv = recv(connSocket, recvBuff, 255, 0);

   if (SOCKET_ERROR == bytesRecv)
   {
    cout<<"Time Client: Error at recv(): "<<WSAGetLastError()<<endl;
    closesocket(connSocket);
    WSACleanup();
    return;
   }
   recvBuff[bytesRecv]='\0';
   arrTime[i]=atoi(recvBuff)-(arrTimeSend[i]);

  }//for 
  average=calculateAverage(arrTime);
  cout<< "The average Delay between Client to Server is "<<average<<" in seconds\n";

 }//findDelay

 if (findRTT)
 {
  int i;
  time_t timerD;
  time_t arrTimeSend[SIZE];
  int arrTime[SIZE];
  strcpy(sendBuff,"GetTime"); 

  for (i=0; i<SIZE; i++)
  {

   //getting time of sending I'm including all operations for sending the request to the server

   arrTimeSend[i]=time (NULL);
   //sending request
   bytesSent = sendto(connSocket, sendBuff, (int)strlen(sendBuff), 0, (const sockaddr *)&server, sizeof(server));

   if (SOCKET_ERROR == bytesSent)
   {
    cout<<"Time Client: Error at sendto(): "<<WSAGetLastError()<<endl;
    closesocket(connSocket);
    WSACleanup();
    return;
   }
  }//for sending
  for (i=0; i<SIZE; i++)
  {
   //recieving data
   bytesRecv = recv(connSocket, recvBuff, 255, 0);

   //getting time of recieving
   timerD = time (NULL);

   if (SOCKET_ERROR == bytesRecv)
   {
    cout<<"Time Client: Error at recv(): "<<WSAGetLastError()<<endl;
    closesocket(connSocket);
    WSACleanup();
    return;
   }

   recvBuff[bytesRecv]='\0';//not needed for calculation , but for future use
   arrTime[i]=difftime(timerD,arrTimeSend[i]);
  }//for receving
  average=calculateAverage(arrTime);
  cout<< "The average RTT time is "<<average<<" in seconds\n";
 }//findRTT
 if (!findRTT && !findDelay)
 {
  bytesSent = sendto(connSocket, sendBuff, (int)strlen(sendBuff), 0, (const sockaddr *)&server, sizeof(server));
  if (SOCKET_ERROR == bytesSent)
  {
   cout<<"Time Client: Error at sendto(): "<<WSAGetLastError()<<endl;
   closesocket(connSocket);
   WSACleanup();
   return;
  }
  cout<<"Time Client: Sent: "<<bytesSent<<"/"<<strlen(sendBuff)<<" bytes of \""<<sendBuff<<"\" message.\n";

  // Gets the server's answer using simple recieve (no need to hold the server's address).
  bytesRecv = recv(connSocket, recvBuff, 255, 0);
  if (SOCKET_ERROR == bytesRecv)
  {
   cout<<"Time Client: Error at recv(): "<<WSAGetLastError()<<endl;
   closesocket(connSocket);
   WSACleanup();
   return;
  }

  recvBuff[bytesRecv]='\0'; //add the null-terminating to make it a string
  cout<<"Time Client: Recieved: "<<bytesRecv<<" bytes of \""<<recvBuff<<"\" message.\n";
 }//(!findRTT && !findDelay) 
}//End of while
  // Closing connections and Winsock.
  cout<<"Time Client: Closing Connection.\n";
  closesocket(connSocket);

  //free the allocating memory 

}//main

//==================
int getRequestFromUser()
{ 
 int num=0; 
 //int index=0;
 //char c;
 cout<<"Choose the information that you intrested in:"<<endl;
 cout<<"(1) - Get time"<<endl;
 cout<<"(2) - Get time without Year"<<endl;
 cout<<"(3) - Get time since epoch - meanning since 1.1.1970"<<endl;
 cout<<"(4) - Get dilay time "<<endl;
 cout<<"(5) - measuring RTT - round trip time"<<endl;
 cout<<"(6) - Get day and month"<<endl;
 cout<<"(0) - Exit"<<endl;

 cin>>num;

 return num;

}
float calculateAverage(int* arr)
{
 int sum=0,i;
 for (i=0; i<SIZE; i++)
  sum+=arr[i];

 return sum/SIZE;
}


//Server

#include <iostream>
using namespace std;
#include <winsock2.h>
#include <string.h>
#include <time.h>
#include <iomanip>


#define TIME_PORT 27015

void main() 
{
    // Initialize Winsock (Windows Sockets).
 // Create a WSADATA object called wsaData.
    // The WSADATA structure contains information about the Windows 
 // Sockets implementation.

 WSAData wsaData; 

 // Call WSAStartup and return its value as an integer and check for errors.
 // The WSAStartup function initiates the use of WS2_32.DLL by a process.
 // First parameter is the version number 2.2.
 // The WSACleanup function destructs the use of WS2_32.DLL by a process.

 if (NO_ERROR != WSAStartup(MAKEWORD(2,2), &wsaData))
 {
        cout<<"Time Server: Error at WSAStartup()\n";
 }

 // Server side:
 // Create and bind a socket to an internet address.
    // After initialization, a SOCKET object is ready to be instantiated.
 // Create a SOCKET object called m_socket. 
 // For this application: use the Internet address family (AF_INET), 
 //       datagram sockets (SOCK_DGRAM), 
 //       and the UDP/IP protocol (IPPROTO_UDP).

    SOCKET m_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

 // Check for errors to ensure that the socket is a valid socket.
 // Error detection is a key part of successful networking code. 
 // If the socket call fails, it returns INVALID_SOCKET. 
 // The "if" statement is used to catch any errors that
 // may have occurred while creating the socket. WSAGetLastError returns an 
 // error number associated with the last error that occurred.

 if (INVALID_SOCKET == m_socket)
 {
        cout<<"Time Server: Error at socket(): "<<WSAGetLastError()<<endl;
        WSACleanup();
        return;
 }

 // For a server to communicate on a network, it must first bind the socket to 
 // a network address.
 // Need to assemble the required data for connection in sockaddr structure.

    // Create a sockaddr_in object called serverService. 

 sockaddr_in serverService;

 // Address family (must be AF_INET - Internet address family).

    serverService.sin_family = AF_INET; 

 // IP address. The sin_addr is a union (s_addr is a unsigdned long (4 bytes) data type).
 // INADDR_ANY means to listen on all interfaces.
 // inet_addr (Internet address) is used to convert a string (char *) into unsigned int.
 // inet_ntoa (Internet address) is the reverse function (converts unsigned int to char *)
 // The IP address 127.0.0.1 is the host itself, it's actually a loop-back.

 serverService.sin_addr.s_addr = INADDR_ANY; //inet_addr("127.0.0.1");

 // IP Port. The htons (host to network - short) function converts an
 // unsigned short from host to TCP/IP network byte order (which is big-endian).

 serverService.sin_port = htons(TIME_PORT);

 // Bind the socket for client's requests.
    // The bind function establishes a connection to a specified socket.
 // The function uses the socket handler, the sockaddr structure (which
 // defines properties of the desired connection) and the length of the
 // sockaddr structure (in bytes).

    if (SOCKET_ERROR == bind(m_socket, (SOCKADDR *) &serverService, sizeof(serverService))) 
 {
  cout<<"Time Server: Error at bind(): "<<WSAGetLastError()<<endl;
        closesocket(m_socket);
  WSACleanup();
        return;
    }

    // Waits for incoming requests from clients.
    // Send and receive data.

 sockaddr client_addr;
 int client_addr_len = sizeof(client_addr);
 int bytesSent = 0;
    int bytesRecv = 0;
 char sendBuff[255];
 char recvBuff[255];

 // Get client's requests and answer them.
 // The recvfrom function receives a datagram and stores the source address.
 // The buffer for data to be received and its available size are 
 // returned by recvfrom. The fourth argument is an idicator 
 // specifying the way in which the call is made (0 for default).
 // The two last arguments are optional and will hold the details of the client for further communication. 
 // NOTE: the last argument should always be the actual size of the client's data-structure (i.e. sizeof(sockaddr)).

 cout<<"Time Server: Wait for clients' requests.\n"; 

 while(true)
 {
  bytesRecv = recvfrom(m_socket, recvBuff, 255, 0, &client_addr, &client_addr_len);
  if (SOCKET_ERROR == bytesRecv)
  {
   cout<<"Time Server: Error at recvfrom(): "<<WSAGetLastError()<<endl;
   closesocket(m_socket);
   WSACleanup();
   return;
  }

  recvBuff[bytesRecv]='\0'; //add the null-terminating to make it a string

  cout<<"Time Server: Recieved: "<<bytesRecv<<" bytes of \""<<recvBuff<<"\" message.\n";

  time_t timer;
  time(&timer);
  char date [10];
  char dayAndMonth [6];

  //1-GetTime
  if (strcmp(recvBuff,"GetTime")==0){
   strcpy(sendBuff, ctime(&timer));
   sendBuff[strlen(sendBuff)-1] = 0;
  }

  //2-GetTimeWithoutYear
  else if (strcmp(recvBuff,"GetTimeWithoutYear")==0){
   struct tm * timeinfo = localtime(&timer);
   strftime (sendBuff,255,"%X",timeinfo);
   sendBuff[strlen(sendBuff)] = 0;
  }

  //3-GetTimeSinceEpoch
  else if (strcmp(recvBuff,"GetTimeSinceEpoch")==0){ 
   timer = time (NULL);
   itoa(timer,sendBuff,10);//converting from int to srting 
   strcat (sendBuff," seconds.");
   sendBuff[strlen(sendBuff)] = 0;
  }
  //6 - GetDayAndMonth
  else if(strcmp(recvBuff, "GetDayAndMonth")==0)
  {
   _tzset;
   _strdate(date);
   strncpy(dayAndMonth, date, 5);
   dayAndMonth[5] = '\0';
   strcpy(sendBuff, dayAndMonth);
   sendBuff[strlen(sendBuff)] = 0;
  }

  // Sends the answer to the client, using the client address gathered
  // by recvfrom. 
  bytesSent = sendto(m_socket, sendBuff, (int)strlen(sendBuff), 0, (const sockaddr *)&client_addr, client_addr_len);
  if (SOCKET_ERROR == bytesSent)
  {
   cout<<"Time Server: Error at sendto(): "<<WSAGetLastError()<<endl;
   closesocket(m_socket);
   WSACleanup();
   return;
  }

  cout<<"Time Server: Sent: "<<bytesSent<<"\\"<<strlen(sendBuff)<<" bytes of \""<<sendBuff<<"\" message.\n"; 
 }

 // Closing connections and Winsock.
 cout<<"Time Server: Closing Connection.\n";
 closesocket(m_socket);
 WSACleanup();
}

3 个答案:

答案 0 :(得分:1)

我的问题在于: server.sin_addr.s_addr = inet_addr(“127.0.0.1”); 在客户路径中。如果我把我的地址改为127.0.0.1,那么服务器就没有响应。 我需要通过wireshark数据包嗅探器来查看此程序中的流量...

答案 1 :(得分:0)

您可能需要先执行一些 ping YOUR_SERVER 命令,或者通过异常处理找出,可能是您的服务器不可用。

答案 2 :(得分:0)

如果我理解正确,你必须使用环回地址(127.0.0.1)与你的服务器通信,问题是,如果这样做,你无法在Wireshark中看到流量。

这是正确的,并假设(如您的代码所示)您在Windows上,我担心您运气不好。请参阅:http://wiki.wireshark.org/CaptureSetup/Loopback

您是否可以更改服务器以使其在另一个地址上进行侦听?