TCP套接字将数据从PC传输到Android设备(Android NDK)

时间:2012-08-08 20:11:47

标签: android c++ sockets android-ndk

我正在努力在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]);
    }
}

此致

1 个答案:

答案 0 :(得分:0)

如果客户端和服务器位于同一台计算机上,则connect()可能会因EADDRINUSE(本地地址已被使用)而失败,因为您将客户端和服务器绑定到相同的端口号:

local_addr.sin_port = htons(PORT);

编辑客户端代码,将客户端绑定到端口0(这意味着内核将为您选择一个未使用的临时端口),然后重试。

即使这不是您遇到的确切问题,也应始终记录库函数返回的错误。 connect()失败后,请记录strerror(errno)

的值