0

プロジェクトの助けが必要です。私はこれが苦手です。これが私のサーバーレシーバーです。このコーディングは、物理 PC に対して行われます。基本的に、物理PCでのこのコーディングは、仮想レシーバーからデータパケットを受信することです。できます。しかし、どういうわけか、パケット情報のデコードに問題があり、これをまったく知りませんでした。

#define HAVE_REMOTE
#define MAX_BUF_SIZE 1024
#define snprintf _snprintf
#define ETH_ALEN 6
#define IP_ALEN 4
#define ARP_REQUEST 1
#define ARP_REPLY 2

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

#pragma comment(lib, "wpcap.lib")
#pragma comment(lib, "Ws2_32.lib")


// A sample of the select() return value
int recvfromTimeOutUDP(SOCKET socket, long sec, long usec)
{
  // Setup timeval variable
  struct timeval timeout;
  struct fd_set fds;

  timeout.tv_sec = sec;
  timeout.tv_usec = usec;
  // Setup fd_set structure
  FD_ZERO(&fds);
  FD_SET(socket, &fds);
  // Return value:
  // -1: error occurred
  // 0: timed out
  // > 0: data ready to be read
  return select(0, &fds, 0, 0, &timeout);
}


int main(int argc, char **argv)
{
  WSADATA            wsaData;
  SOCKET             ReceivingSocket;
  SOCKADDR_IN        ReceiverAddr;
  int                Port = 5150;
  char          ReceiveBuf[6000];
  int                BufLength = 6000;
  SOCKADDR_IN        SenderAddr;
  int                SenderAddrSize = sizeof(SenderAddr);
  int                ByteReceived = 5, SelectTiming, ErrorCode;
  char ch = 'Y';

 // Initialize Winsock version 2.2
 if( WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
 {
     printf("Server: WSAStartup failed with error %ld\n", WSAGetLastError());
     return -1;
 }
 else
       printf("Server: The Winsock DLL status is %s.\n", wsaData.szSystemStatus);

       // Create a new socket to receive datagrams on.
       ReceivingSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

       if (ReceivingSocket == INVALID_SOCKET)
       {
         printf("Server: Error at socket(): %ld\n", WSAGetLastError());
         // Clean up
         WSACleanup();
         // Exit with error
         return -1;
        }
        else
        printf("Server: socket() is OK!\n");

        // Set up a SOCKADDR_IN structure that will tell bind that we
        // want to receive datagrams from all interfaces using port 5150.

        // The IPv4 family
        ReceiverAddr.sin_family = AF_INET;
        // Port no. 5150
        ReceiverAddr.sin_port = htons(Port);
        // From all interface (0.0.0.0)
        ReceiverAddr.sin_addr.s_addr = htonl(INADDR_ANY);

        // Associate the address information with the socket using bind.
        // At this point you can receive datagrams on your bound socket.
        if (bind(ReceivingSocket, (SOCKADDR *)&ReceiverAddr, sizeof(ReceiverAddr)) == SOCKET_ERROR)
         {
                   printf("Server: bind() failed! Error: %ld.\n", WSAGetLastError());
                   // Close the socket
                   closesocket(ReceivingSocket);
                   // Do the clean up
                   WSACleanup();
                   // and exit with error
                   return -1;
                 }
                 else
                 printf("Server: bind() is OK!\n");

       // Some info on the receiver side...
      getsockname(ReceivingSocket, (SOCKADDR *)&ReceiverAddr, (int *)sizeof(ReceiverAddr));

      printf("Server: Receiving IP(s) used: %s\n", inet_ntoa(ReceiverAddr.sin_addr));
      printf("Server: Receiving port used: %d\n", htons(ReceiverAddr.sin_port));
      printf("Server: I\'m ready to receive a datagram...\n");

      SelectTiming = recvfromTimeOutUDP(ReceivingSocket, 100, 0);

      switch (SelectTiming)
      {
         case 0:
             // Timed out, do whatever you want to handle this situation
             printf("Server: Timeout while waiting for client!...\n");
             break;
         case -1:
             // Error occurred, maybe we should display an error message?
            // Need more tweaking here and the recvfromTimeOutUDP()...
             printf("Server: Some error encountered with code number: %ld\n", WSAGetLastError());
             break;
         default:
             {
                  while (1)


                  {
                       // Call recvfrom() to get it then display the received data...
                       ByteReceived = recvfrom(ReceivingSocket, ReceiveBuf, BufLength,
                                                0, (SOCKADDR *)&SenderAddr, &SenderAddrSize);
                       if ( ByteReceived > 0 )
                       {
                           printf("\n\nServer: Total Bytes received: %d\n", ByteReceived);
                           printf("Server: The data is \"%s\"\n", ReceiveBuf);
                       }
                       else if ( ByteReceived <= 0 )
                            printf("Server: Connection closed with error code: %ld\n",
                                        WSAGetLastError());
                       else
                            printf("Server: recvfrom() failed with error code: %d\n",
                                    WSAGetLastError());

                       // Some info on the sender side
                       getpeername(ReceivingSocket, (SOCKADDR *)&SenderAddr, &SenderAddrSize);
                       printf("Server: Sending IP used: %s\n", inet_ntoa(SenderAddr.sin_addr));
                       printf("Server: Sending port used: %d\n", htons(SenderAddr.sin_port));

                       printf("TIME -", ReceiveBuf);
                  }

             }





        }



       // When your application is finished receiving datagrams close the socket.
          printf("Server: Finished receiving. Closing the listening socket...\n");
          if (closesocket(ReceivingSocket) != 0)
              printf("Server: closesocket() failed! Error code: %ld\n", WSAGetLastError());
          else
              printf("Server: closesocket() is OK...\n");

      // When your application is finished call WSACleanup.
       printf("Server: Cleaning up...\n");
       if(WSACleanup() != 0)
          printf("Server: WSACleanup() failed! Error code: %ld\n", WSAGetLastError());
       else
          printf("Server: WSACleanup() is OK\n");
       // Back to the system
       // system("PAUSE");
       return 0;
 }

以下は、物理 PC の CLI で取得した例です。これは、仮想受信機から受信したパケットごとのパケットだと思います。私はそれをどのようにデコードするのか混乱しました

時間|送信者 Mac アドレス|ターゲット Mac アドレス|パケット長|イーサ タイプ|送信元 IP アドレス| 宛先 IP アドレス

 Server: Total Bytes received: 4000
 Server: The data is "Time : 10:32:24.759385   
 0050568214540064403a1c000800450000285aeb40007f06b0c4ac10a40bac10f3f3c0990d3d740222860176142f5010054e40620000000000000000"
 Server: Sending IP used: 172.16.243.243
 Server: Sending port used: 59079


 Server: Total Bytes received: 4000
 Server: The data is "Time : 10:32:24.759385
 0050568214540064403a1c000800450000285aeb40007f06b0c4ac10a40bac10f3f3c0990d3d740222860176142f5010054e40620000000000000000"
 Server: Sending IP used: 172.16.243.243
 Server: Sending port used: 59080

パケット情報分析をデコードするにはどうすればよいですか?

このようなものをデコードします。

時間|送信者 Mac アドレス|ターゲット Mac アドレス|パケット長|イーサ タイプ|送信元 IP アドレス| 宛先 IP アドレス

4

1 に答える 1

0

おそらく、データを送信するためにバイトバッファにデータを書き込んだでしょう。それを受信するとき、あなたはそれを書いたのと同じ方法であなたの受信バッファからデータを読み戻す必要があります。受信コードしか表示できないため、送信内容を推測することしかできませんが、たとえば、4 x 4バイトの整数をcharバッファーに書き込んでから、ソケットを介して送信するとします。受信コードは次のようなことをする必要があります

   int iData1 = 0;
   int iData2 = 0;
   int iData3 = 0;
   int iData4 = 0;
   char* szIt = ReceiveBuff;          // set a pointer to start of receive buffer
   memcpy(&iData1,szIt,sizeof(int);   // memcpy first item
   szIt += sizeof(int);               // point to location in buffer of next item   
   memcpy(&iData2,szIt,sizeof(int);   // memcpy second....
   szIt += sizeof(int);

   // Now do the rest of the data items until you have read 
   // everything in the packet

次の項目についても同様です。異なるタイプがある場合は、それらのタイプのサイズだけポインターをインクリメントする必要があります。同じことを行う方法は他にもありますが、これは機能します。これを行うときに考慮する必要がある非常に重要なことは、送受信するマシンの使いやすさです。データにビッグエンディアンを書き込むように強制して、クライアントがそれ自体がリトルエンディアンであるかどうかを認識して処理できるようにすることができます。

重要なのは、送信するデータの順序と、クライアント側で同じようにバイトバッファを解釈することです。

お役に立てれば

于 2012-07-09T10:11:38.233 に答える