2012-02-08 10 views
0

私は、TCP-IPサーバーとクライアントにこれらの簡単なサンプルC++コードを使用してBSDソケットプログラミングを学習し、理解しようとしています。私はsocket()、bind()、listen()、accept()、read/recv()のような標準APIを読んだことがあり、g ++/Linuxでコンパイルするコードもあります。シンプルなソケットプログラミングコードの動作

私がやりたいことは、実際にはサーバーコードを実行してからクライアントを使用して接続し、クライアントからサーバーにデータを送信してその逆も行うことです受け取ったデータ。私の同じネットワークセグメントの2つのLinuxボックス(Ubuntu)内のすべて。私はこれらの2台のLinuxマシンにプライベートIPv4アドレスを与えました。

上記のネットワーク設定でこれを達成するには、これを達成するための設定と、以下のサーバーコードとクライアントコードのコード変更が必要ですか?私は本当にリアルタイムでネットワーク上で動作して見たいですか?

さらにコードへのポインタは、実践的なソケットプログラミング/ネットワークプログラミングを学ぶためのブログ記事が役立ちます。サーバー側では

//TCP SERVER 
#include<sys/socket.h> 
#include<netinet/in.h> 
#include<stdio.h> 
#include<string.h> 
#include<stdlib.h> 
#include <arpa/inet.h> 
//#include <fcntl.h> 
#include <unistd.h> 

main() 
{ 
    char buf[100]; 
    socklen_t len; 
    int k,sock_desc,temp_sock_desc; 
    struct sockaddr_in client,server; 
    memset(&client,0,sizeof(client)); 
    memset(&server,0,sizeof(server)); 
    sock_desc = socket(AF_INET,SOCK_STREAM,0); 
    server.sin_family = AF_INET; server.sin_addr.s_addr = inet_addr("127.0.0.1"); 
    server.sin_port = 7777; 
    k = bind(sock_desc,(struct sockaddr*)&server,sizeof(server)); 
    k = listen(sock_desc,20); len = sizeof(client); 
    temp_sock_desc = accept(sock_desc,(struct sockaddr*)&client,&len); 
    while(1) 
    {  
     k = recv(temp_sock_desc,buf,100,0);  
     if(strcmp(buf,"exit")==0)   
      break;  
     if(k>0)   
      printf("%s",buf); 
    } close(sock_desc); 
    close(temp_sock_desc); 
    return 0; 
} 

//TCP CLIENT 
#include<sys/socket.h> 
#include<netinet/in.h> 
#include<stdio.h> 
#include<string.h> 
#include<stdlib.h> 
#include <arpa/inet.h> 
//#include <fcntl.h> 
#include <unistd.h> 

main() 
{ 
    char buf[100]; 
    struct sockaddr_in client; 
    int sock_desc,k; 
    sock_desc = socket(AF_INET,SOCK_STREAM,0); 
    memset(&client,0,sizeof(client)); 
    client.sin_family = AF_INET; 
    client.sin_addr.s_addr = inet_addr("127.0.0.1"); 
    client.sin_port = 7777; 
    k = connect(sock_desc,(struct sockaddr*)&client,sizeof(client)); 
    while(1) 
    {  
     gets(buf);  
     k = send(sock_desc,buf,100,0);  
     if(strcmp(buf,"exit")==0)   
      break; 
    } 
    close(sock_desc); 
    return 0; 
} 
+0

何を試しましたか?何が起こったのですか? – Useless

+0

これは最も簡単な例ですか? – Beta

+0

@Useless Linux端末で実行可能ファイルとしてサーバーコードを実行しました。同じボックスの別の端末で、私はクライアントコードを実行しました。クライアント実行可能端末ウィンドウに何かを入力します。 server.Thatsで受け取ったものは、このデータフローがこのソケットコードの例でどのように起こるかを理解したいと思っています。 – goldenmean

答えて

2

あなたはどこからでも接続を可能にするために0.0.0.0にアドレス127.0.0.1を変更する必要があります。クライアントコードの代わりにtelnetを使用して、サーバーが期待どおりに動作していることを確認することもできます。また、さまざまなLinuxにsnoopコマンドがあるかどうか調べてください。クライアント側では

あなたは次の変更を加える必要があり、サーバマシン

+0

以下の変更は試みましたが、接続が確立されていませんでした。/ data trasnfer 1]サーバーコードソケットIPアドレスを0.0.0.0に変更しました。ビルド。実行します。次に、別の端末からssh(Linux PCでtelnetがブロックされている)を試みました。あなたがtelnetを使用すると言ったとき、正確に何を意味したのですか? 2]また、クライアントコードのソケットアドレスを、実際に実行されたプライベートIPアドレスに変更しました。私が見ることができたのと同じ振る舞いも転送も接続も起こっていません。私は何か誤解しましたか?この例で使用されているポート番号を問題にすることはできますか? – goldenmean

2

のIPアドレスを使用する必要があります。

ポート番号 - server.sin_port = htons(7777); クライアント - - client.sin_port = htons(7777);

サーバ - それは任意のアドレスから受け入れることを得る - すなわちserver.sin_addr.s_addr = INADDR_ANY;

希望やや

4

追加することができますhtons

すなわちサーバーを使用しますあなたのコードにいくつかのエラー処理、おそらく何かを明らかにするでしょう:

サーバー:

#include <sys/socket.h> 
#include <netinet/in.h> 
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <arpa/inet.h> 
//#include <fcntl.h> 
#include <unistd.h> 

main() 
{ 
    int sock_desc = socket(AF_INET, SOCK_STREAM, 0); 
    if (sock_desc == -1) 
    { 
     printf("cannot create socket!\n"); 
     return 0; 
    } 

    struct sockaddr_in server; 
    memset(&server, 0, sizeof(server)); 
    server.sin_family = AF_INET; 
    server.sin_addr.s_addr = INADDR_ANY; 
    server.sin_port = htons(7777); 
    if (bind(sock_desc, (struct sockaddr*)&server, sizeof(server)) != 0) 
    { 
     printf("cannot bind socket!\n"); 
     close(sock_desc); 
     return 0; 
    } 

    if (listen(sock_desc, 20) != 0) 
    { 
     printf("cannot listen on socket!\n"); 
     close(sock_desc); 
     return 0; 
    } 

    struct sockaddr_in client; 
    memset(&client, 0, sizeof(client)); 
    socklen_t len = sizeof(client); 
    int temp_sock_desc = accept(sock_desc, (struct sockaddr*)&client, &len); 
    if (temp_sock_desc == -1) 
    { 
     printf("cannot accept client!\n"); 
     close(sock_desc); 
     return 0; 
    } 

    char buf[100]; 
    int k; 

    while(1) 
    {  
     k = recv(temp_sock_desc, buf, 100, 0);  
     if (recv == -1) 
     { 
      printf("\ncannot read from client!\n"); 
      break; 
     } 

     if (recv == 0) 
     { 
      printf("\nclient disconnected.\n"); 
      break; 
     } 

     if (k > 0)   
      printf("%*.*s", k, k, buf); 

     if (strcmp(buf, "exit") == 0)   
      break;  
    } 

    close(temp_sock_desc); 
    close(sock_desc); 

    printf("server disconnected\n"); 
    return 0; 
} 

クライアント:

#include <sys/socket.h> 
#include <netinet/in.h> 
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <arpa/inet.h> 
//#include <fcntl.h> 
#include <unistd.h> 

main() 
{ 
    int sock_desc = socket(AF_INET, SOCK_STREAM, 0); 
    if (sock_desc == -1) 
    { 
     printf("cannot create socket!\n"); 
     return 0; 
    } 

    struct sockaddr_in client; 
    memset(&client, 0, sizeof(client)); 
    client.sin_family = AF_INET; 
    client.sin_addr.s_addr = inet_addr("127.0.0.1"); 
    client.sin_port = htons(7777); 

    if (connect(sock_desc, (struct sockaddr*)&client, sizeof(client)) != 0) 
    { 
     printf("cannot connect to server!\n"); 
     close(sock_desc); 
    } 

    char buf[100]; 
    char c = '\n'; 
    char *p_buf; 
    int k, len; 

    while(1) 
    {  
     gets(buf); 

     len = strlen(buf); 
     p_buf = buf; 

     while (len > 0) 
     { 
      k = send(sock_desc, p_buf, len, 0);  
      if (k == -1) 
      { 
       printf("cannot write to server!\n"); 
       break; 
      } 

      p_buf += k; 
      len -= k; 
     } 

     k = send(sock_desc, &c, 1, 0);  
     if (k == -1) 
     { 
      printf("cannot write to server!\n"); 
      break; 
     } 

     if (strcmp(buf, "exit") == 0)   
      break; 
    } 

    close(sock_desc); 
    printf("client disconnected\n"); 

    return 0; 
} 
+0

send()またはrecv()からの戻り値が-1の場合、errnoがEINTRに設定されているかどうかを常にチェックし、同じ場合は同じ呼び出しを繰り返します。そうしないと、中断により原因不明の障害が発生する可能性があります。 –

+0

これは 'accept()'と 'connect()'にも当てはまります。 –

+0

すてきなサンプルコード!ありがとうレミー!あなたのコーディングスタイルから多くを学ぶことができます –

0

それはこのようにする必要があります。

if (connect(sock_desc, (struct sockaddr*)&client, sizeof(client)) != 0) 
関連する問題