2

私はAndroidデバイス(クライアント)とPC(サーバー)の間にTCPソケットを実装するために取り組んでいます。これは、c ++(Android NDK)によって実装されるコードです。

すべてが正常に機能しています。サーバー側で実行すると、出力「サーバーが起動します」がクライアントへの接続を待機します。反対側では、クライアントに対して実行すると、サーバーに接続するまで機能し、このエラー「ソケット接続サーバーへの接続エラー」が見つかります。

誰かが私に欲しいと言うことができますか?

マトリックス16*16をサーバーからクライアントに転送し、クライアントからサーバーに形成したいという考え...

サーバ側:

MyServerThread::MyServerThread()
{
    startServer();
}
void MyServerThread::run()
{
    //std::cout<<"hi"<<std::endl;
    for(int i=0;i<16;i++)
        matrix[i]=(float)i;
    memcpy(buf,matrix,4*16);
    sendMSG();
}

//TCP socket
/* now create the server socket
   make it an IPV4 socket (PF_INET) and stream socket (TCP)
   and 0 to select default protocol type */
if ( (server_skt = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){
    std::cerr<<"socket creation failed"<<std::endl;
    exit(1);
}

//Initail, bind to port
/* now fill in values of the server sockaddr_in struct
   s_addr and sin_port are in Network Byte Order (Big Endian)
   Since Intel CPUs use Host Byte Order (Little Endian), conversion
   is necessary (e.g. htons(), and htonl() */
server_addr.sin_family = AF_INET;//IPv4
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
memset(server_addr.sin_zero, 0, 8);

//binding

 /* now bind server port
       associate socket (server) with IP address:port (server_addr) */

if ( bind(server_skt, (struct sockaddr*)&server_addr, sizeof(struct sockaddr)) == -1 ){
    std::cerr<<"socket bind failed"<<std::endl;
    exit(1);
}

int queueSize=1;
//Start listening, wait for connection from client with a pending queue of size
if ( listen(server_skt, queueSize) == -1 ){
    std::cerr<<"socket listen failed"<<std::endl;
    exit(1);
}

//Wait for connect!
bool gotClient=false;
while(!gotClient){
    sin_size = sizeof(struct sockaddr_in);
    socklen_t temp=sin_size;
    std::cout<<"server starts"<<std::endl;
    if ( (client_skt = accept(server_skt, (struct sockaddr*)&clients_addr, &temp)) == -1 ){
        std::cerr<<"socket error"<<std::endl;}
    else
    {
        gotClient=true;
        std::cout<<"Got client"<<std::endl;
    }
}

    void MyServerThread::sendMSG()
{
    if ( (numbytes = send(client_skt, buf, strlen(buf),0)) == -1){
        std::cerr<<"server, normal send error"<<std::endl;
        exit(1);
    }
}

void MyServerThread::recvMSG()
{
    if ( (numbytes = recv(client_skt, buf, bufferSize,0)) == -1 ){
        std::cerr<<"server, normal recv error"<<std::endl;
        exit(1);
    }
}

クライアント側:

Client::Client()
{

}
void Client::startClient()
{
    /* now fill in sockaddr_in for remote address */
    serv_addr.sin_family = AF_INET;
    /* save the server IP (input from Java */
    serv_addr.sin_addr.s_addr = inet_addr(serverIP);
    /* set port */
    serv_addr.sin_port = htons(PORT);
    memset(serv_addr.sin_zero, 0, 8);

    /* create local stream socket */
    client_skt = socket(PF_INET, SOCK_STREAM, 0);
    if (client_skt < 0) {
        __android_log_print(ANDROID_LOG_ERROR,"jni client","socket creation error");
        exit(-1);
    }

    /* bind local socket to any port number */
    local_addr.sin_family = AF_INET;
    local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    //local_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    local_addr.sin_port = htons(PORT);
    memset(local_addr.sin_zero, 0, 8);

    rc = bind(client_skt, (struct sockaddr *) &local_addr, sizeof(local_addr));

    if (rc < 0)
    {
        __android_log_print(ANDROID_LOG_ERROR,"jni client","socket bind error");
        exit(1);
    }
    __android_log_print(ANDROID_LOG_INFO,"jni client","client start finished");


}
void Client::connectServer()
{
    __android_log_print(ANDROID_LOG_INFO,"jni client","connect to server starts");
    /* connect to server */
    rc = connect(client_skt, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
    if (rc < 0)
    {
        __android_log_print(ANDROID_LOG_ERROR,"jni client","socket connect to server error");
        exit(1);
    }
    __android_log_print(ANDROID_LOG_ERROR,"jni client","server connected");
}
void Client::sendMSG()
{
    if ( (numbytes = send(client_skt, "hello!", strlen("hello!"),0) )== -1 ){
        __android_log_print(ANDROID_LOG_ERROR,"jni client","send error");
        //exit(1);
    }

}
void Client::recvMSG()
{
    if ( (numbytes = recv(client_skt, buf, bufferSize,0) ) == -1 ){
        __android_log_print(ANDROID_LOG_ERROR,"jni client","recv error");
        //exit(1);
    }
    else
    {
        memcpy (matrix, buf, numbytes);
        for(int i=0;i<4;i++)
            __android_log_print(ANDROID_LOG_INFO,"matrix","%f, %f, %f, %f",matrix[i*4],matrix[i*4+1],matrix[i*4+2],matrix[i*4+3]);
    }
}

よろしく、

4

1 に答える 1

0

クライアントとサーバーが同じマシン上にある場合、クライアントとサーバーのconnect()両方を同じポート番号にバインドしているため、EADDRINUSE (ローカル アドレスは既に使用されています) で失敗する可能性があります。

local_addr.sin_port = htons(PORT);

クライアント コードを編集し、クライアントをポート 0 にバインドして (カーネルが未使用の一時ポートを選択することを意味します)、再試行します。

これがあなたが抱えている正確な問題ではない場合でも、ライブラリ関数によって返されたエラーを常にログに記録する必要があります。connect()失敗した後、 の値をログに記録しますstrerror(errno)

于 2012-08-08T20:55:27.807 に答える