2017-10-24 51 views
-1

クライアントに2つの文字列を入力し、それらを構造体とともにサーバーに送信する必要があります。次にサーバーはc = a + bを実行し、{ a, b, c }というニュース構造をクライアントに送信します。 aまたはbが受信された場合、サーバーはquitです。サーバーはクライアントbyeに送信します。TCPを介して構造体を送受信する

クライアントは構造体を受け取り、cを印刷します。 byeの場合は接続を終了し、そうでない場合はabの入力を要求するように戻り、サイクルが再び開始されます。

クライアント:

#if defined WIN32 
    #include <Winsock2.h> 
    #else 
    #define closesocket close 
    #include <sys/socket.h> 
    #include <arpa/inet.h> 
    #include <unistd.h> 
    #endif 
    #include <stdio.h> 
    #include <stdlib.h> 
    #include <string.h> 

    #define BUFSIZE 30 

    void ClearWinSock() { 
    #if defined WIN32 
     WSACleanup(); 
    #endif 
    } 

    //-----------------------------INIZIALIZZAZIONE WSADATA 

    int main (void) { 
    #if defined WIN32 

     WSADATA wsaData; 
     int iResult = WSAStartup (MAKEWORD (2,2), &wsaData); 

     if (iResult !=0) { 
      printf ("error at WSASturtup\n"); 
      return 0; 
      } 

    #endif 

    //--------------------------------CREAZIONE SOCKET 

     int Csocket; 

     Csocket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); 

     if (Csocket < 0) { 

     printf ("socket creation failed"); 
     closesocket (Csocket); 
     ClearWinSock(); 
     return 0; 
     } 

     char s_address[BUFSIZE]; 
       printf ("Inserisci l'indirizzo dell'host a cui connetterti\n"); 
       scanf ("%s", s_address); 

       int port; 
       printf ("Inserisci la porta a cui connetterti\n"); 
       scanf("%d", &port); 

       struct sockaddr_in sad; 
        memset (&sad, 0, sizeof(sad)); 
        sad.sin_family = AF_INET; 
        sad.sin_addr.s_addr = inet_addr(s_address); 
        sad.sin_port = htons (port); 

    //------------------------------CONNESSIONE AL SERVER 

     if (connect(Csocket, (struct sockaddr*) &sad, sizeof(sad)) < 0) { 
      printf ("failed to connect\n"); 
      closesocket (Csocket); 
      ClearWinSock(); 
      return 0; 
     } 

    //-----------------------------RICEZIONE STRINGA DAL SERVER 

     char buf[BUFSIZE]; 

     int read = recv (Csocket, buf, BUFSIZE - 1, 0); 

     if (read <=0) { 

     printf ("Qualcosa non và!\n"); 
     } 

     else { 
     buf[read] = '\0'; //tappo stringa per sicurezza 
     printf("Server scrive: %s\n", buf); 
     } 


    //------------------------------STRUTTURA DI STRINGHE 

     struct stringab { 
           char a[30]; 
           char b[30]; 
           char c[70]; 
          } ab; 


          void* abptr = &ab; 


       printf ("Inserisci prima stringa\n"); 
       scanf ("%s", ab.a); 


          printf ("Inserisci seconda stringa\n"); 
          scanf ("%s", ab.b); 



     if (send(Csocket, (char*)abptr, sizeof(ab), 0) != sizeof(ab)) { 
       printf("client-send() sent a different number of bytes than expected"); 
       closesocket(Csocket); 
       ClearWinSock(); 
       system ("pause"); 
       return 0; 
      } 

printf ("\n"); 
    closesocket (Csocket); 
    system ("pause"); 
    ClearWinSock(); 
    return 0; 

    } 

サーバー:

#if defined WIN32 
#include <Winsock2.h> 
#else 
#define closesocket close 
#include <sys/socket.h> 
#include <arpa/inet.h> 
#include <unistd.h> 
#endif 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#define BUFSIZE 30 

void ClearWinSock() { 
#if defined WIN32 
    WSACleanup(); 
#endif 
} 

int main(void) { 

//---------------------------INIZIALIZZAZIONE WSADATA 

#if defined WIN32 

    WSADATA wsaData; 
    int iResult = WSAStartup(MAKEWORD(2,2), &wsaData); 
    if (iResult != 0) { 
     printf ("Error at WSAStartup"); 
     return 0; 
    } 

#endif 

//-------------------------------CREAZIONE SOCKET 

    int Mysocket; 
    Mysocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); 

    //Valutare la presenza di errori per assicurarsi che la socket sia valida. 
    if (Mysocket < 0) { 
     printf("socket creation failed\n"); 
     return 0; 
    } 

    //Assegnazione indirizzo alla socket. 
    struct sockaddr_in sad; 
    memset(&sad, 0, sizeof(sad)); 
    sad.sin_family = AF_INET; 
    sad.sin_addr.s_addr = inet_addr ("127.0.0.1"); 
    sad.sin_port = htons (9888); 

//------------------------ASSEGNAZIONE PORTA E IP ALLA SOCKET 

if (bind(Mysocket, (struct sockaddr*) &sad, sizeof(sad)) < 0) { 
    printf ("bind() failed\n"); 
    closesocket(Mysocket); 
    return 0; 
} 

//---------------------------SETTAGGIO SOCKET ALL'ASCOLTO 

int qlen = 10; //numero client che il server può gestire 

if (listen (Mysocket, qlen) < 0) { 

    printf("listen() failed\n"); 
    closesocket(Mysocket); 
    return 0; 
} 

struct sockaddr_in cad; // struttura per l'indirizzo del cient 
int Csocket;    // descrittore socket per il client 
int clientlen;   // lunghezza indirizzo del client 

//------------------------------ACCETTA LA CONNESSIONE 

while (1) { 

    printf("In attesa di un client con cui comunicare...\n"); 
    memset(&cad, 0, sizeof(cad)); 
    clientlen = sizeof(cad);  // assegna la dimensione dell'indirizzo del client 

    if((Csocket = accept(Mysocket, (struct sockaddr*) &cad, &clientlen)) < 0) { 
     printf ("accept failed\n"); 
     closesocket(Mysocket); 
     ClearWinSock(); 
     return 0; 
    } 


    printf("Connessione stabilita con il client il cui indirizzo e' %s \n\n", inet_ntoa(cad.sin_addr)); 

//---------------------------------------INVIO STRINGA AL CLIENT 

    char* inputString = "Connessione avvenuta!"; 
    int stringlen = strlen(inputString); 


    if (send(Csocket, inputString, stringlen, 0) != stringlen) { 
     printf("client-send() sent a different number of bytes than expected"); 
     closesocket(Csocket); 
     ClearWinSock(); 
     system ("pause"); 
     return 0; 
    } 

printf ("\n"); 
closesocket (Csocket); 
system ("pause"); 
ClearWinSock(); 
return 0; 

} 

だから、私は、このようにサーバに構造体を送ったのですか?サーバーはどのようにしてrecv()この構造体にできますか?c = a + b構造体を再構築して再送信しますか?

+1

送信エラーが発生しましたか?あなたは他の側に構造をそのまま受け取りましたか?あなたはあなたが持っている問題について詳しく教えてもらえますか?そして[良い質問をする方法を読む](http://stackoverflow.com/help/how-to-ask)を読んで、[最小限で完全で証明可能な例]を作成する方法を学んでください(http:// stackoverflow .com/help/mcve)。 Eric Lippertによる[小さなプログラムのデバッグ方法](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)も読んでください。 –

+2

トピックの(私は思う):この方法でネットワークを介して構造体を送ることに注意してください。クライアントとサーバが異なるタイプである場合、異なるコンパイラによってコンパイルされたプログラムなどは、非常に間違っている可能性があります。ほとんどの場合、少なくとも異なるレイアウトを避けるために、パックされた構造体が必要です。 – 4386427

+0

私はコードを起動し、2つの文字列の入力が機能します。送信側でエラーはないようです。私はそれが問題なく受信されているかどうかわからないので、私はサーバー側で構造体を受け取る方法を知らない。 – mark

答えて

0

私は、送信側の問題を解決し、このように受信側:

send(Csocket, (char*)abptr, sizeof(ab), 0); 

recv (Csocket, (char*)abptr, sizeof(ab), 0); 

だから私は両方の側の構造体のポインタで構造体を通過しました。私はそれがローカルホスティングの良い解決策だと思う、多分あなたはネット(セキュリティの理由)のためのより良いものが必要です。

関連する問題