2

TCPソケットを使用してサーバーと1つのクライアント間で通信するプロジェクトがあります。今のところ、私は1台のコンピューターでこれを行っているので、両側でバインドおよび接続するアドレスに「127.0.0.1」のローカルアドレスを使用しましたが、正常に機能しました。これで、クライアントとして機能する2台目のコンピューターができましたが、それに応じてアドレスを変更する方法がわかりません。それらはインターネットに接続されていないネットワークを介して接続されています。コードがこのようになる前に-

サーバー-

 struct addrinfo hints;
struct addrinfo *servinfo; //will point to the results

//store the connecting address and size
struct sockaddr_storage their_addr;
socklen_t their_addr_size;


memset(&hints, 0, sizeof hints); //make sure the struct is empty
hints.ai_family = AF_INET; //local address
hints.ai_socktype = SOCK_STREAM; //tcp
hints.ai_flags = AI_PASSIVE; //use local-host address

//get server info, put into servinfo
if ((status = getaddrinfo("127.0.0.1", port, &hints, &servinfo)) != 0) {
    fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
    return false;
}

//make socket
fd = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol);
if (fd < 0) {
    printf("\nserver socket failure %m", errno);
    return false;
}

//allow reuse of port
int yes=1;
if (setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(char*) &yes,sizeof(int)) == -1) {
    perror("setsockopt");
    return false;
}

//unlink and bind
unlink("127.0.0.1");
if(bind (fd, servinfo->ai_addr, servinfo->ai_addrlen) < 0) {
    printf("\nBind error %m", errno);
    return false;
}

クライアント -

struct addrinfo hints;
struct addrinfo *servinfo; //will point to the results

memset(&hints, 0, sizeof hints); //make sure the struct is empty
hints.ai_family = AF_INET; //local address
hints.ai_socktype = SOCK_STREAM; //tcp
hints.ai_flags = AI_PASSIVE; //use local-host address

//get server info, put into servinfo
if ((status = getaddrinfo("127.0.0.1", port, &hints, &servinfo)) != 0) {
    fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
    return false;
}

//make socket
fd = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol);
if (fd < 0) {
    printf("\nserver socket failure %m", errno);
    return false;
}

//connect
if(connect(fd, servinfo->ai_addr, servinfo->ai_addrlen) < 0) {
    printf("\nclient connection failure %m", errno);
    return false;
}

簡単なはずですが、IPを変更して機能させる方法がわかりません。サーバーコンピューターのIPアドレスをこれらの行の引用符で設定してみました-if((status = getaddrinfo( "127.0.0.1"、port、&hints、&servinfo))!= 0)and unlink( "127.0.0.1");

次に、クライアントコードのアドレスをこの行のクライアントコンピューターのIPアドレスに変更します-if((status = getaddrinfo( "127.0.0.1"、port、&hints、&servinfo))!= 0)

私がそれをするときはいつでも、それは私に接続が拒否されたことを告げます。また、サーバーのアドレスをクライアントの行に入れ、クライアントのアドレスをサーバーの行に入れるという逆の方法を、他のいくつかの試みとともに試しました。この時点で、私はただ推測しているような気がします。では、誰かがこれを1台のコンピューターでローカルアドレスを使用する方法から2台のコンピューターに接続する方法に変更する方法を理解するのを手伝ってもらえますか?どんな助けでも大歓迎です。

4

3 に答える 3

1

まず、unlink("127.0.0.1");ここでは完全に間違っています。そうしないでください。

次に、2台のコンピューターが何らかのネットワークで接続されています。両方にIPアドレスが必要です。127.0.0.1クライアントとサーバーの両方でサーバーのIPアドレスに置き換えます。サーバーは事前にクライアントのアドレスを知っている必要はありません-それはaccept(2)呼び出しからその情報を取得します。クライアントは、接続先を知るためにサーバーのアドレスを必要とします。サーバーは、呼び出しのために独自のアドレスを必要としbind(2)ます。

于 2011-08-10T21:07:20.840 に答える
1

主な問題は、クライアントコードにAI_PASSIVEを配置することです。AI_PASSIVEは、サーバーのみを対象としています(これがシグナルです)。

また、サーバー側では、まず最初にunlinkを呼び出さないでください。これはAF_UNIXソケット専用であり、AF_INET用ではありません。次に、サーバー側のgetaddrinfo行に「127.0.0.1」を入力する必要はありません。使用可能なすべてのアドレスにバインドするには、NULLを使用することをお勧めします。

これらを変更すれば、コードは機能するはずです。ただし、実際には、ai_nextポインターを使用してgetaddrinfoの結果をループし、成功した最初の結果を使用して各結果に接続しようとすることになっています。

于 2011-08-10T21:08:19.980 に答える
0

Connection Refused通常、クライアントがを受け取ったRSTことを意味しますSYN。これはほとんどの場合、接続しようとしているポートのサーバーにリスニングソケットがないことが原因です。

  1. サーバーを実行する
  2. CLIで、と入力しnetstat -antます。ポートに状態のエントリが表示LISTENされますか?

何かのようなもの:

tcp4       0      0  *.3689                 *.*                    LISTEN  

私はあなたがそうしないに違いない、そしてそれ故にあなたのサーバーリスニングソケットに問題がある。私はまた、あなたがこの行に加えた変更に賭けます:

if ((status = getaddrinfo("127.0.0.1", port, &hints, &servinfo)) != 0) {

正しくありませんでした。サーバー上でそのIPをに変更し0.0.0.0て、システム上の任意のIPにバインドするように指示してみてください。クライアントでは、その行にサーバーのIPアドレスが含まれている必要があります。unlink()サーバー内の呼び出しも削除する必要があります。不要。

リスニングソケットがある場合、SYNをブロックしているファイアウォールまたはボックスの間に何かがある可能性があります。service iptables stop両方のシステムのCLIで入力してみてください。

于 2011-08-10T21:11:25.640 に答える