首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在客户端更改网络IP后,可以在C(服务器)中发送,但不能从Android (客户端)中接收

问在客户端更改网络IP后,可以在C(服务器)中发送,但不能从Android (客户端)中接收
EN

Stack Overflow用户
提问于 2015-03-19 06:36:51
回答 1查看 182关注 0票数 1

编辑:首先,我知道TCP和UDP是什么,以及它们的区别,但是如何解释我可以在客户端从服务器接收,但不能发送,如下所示...

我用C语言做了一个服务器应用程序,用Java做了一个客户端应用程序,我把它部署到Android上。我有一个奇怪的问题,我不能克服。

当我的手机IP改变(例如,当切换到移动网络时,从Wifi,或相反),C中的应用程序不再能够接收数据,只是发送,即使手机发送了数据,没有任何错误。

重新连接到同一网络时不会发生这种情况。

我尝试了很多东西,最后得到了这个,用C:

代码语言:javascript
复制
void *receive_thread(){
    pthread_detach(pthread_self());

    struct sockaddr_in dest; /* socket info about the machine connecting to us */
    struct sockaddr_in serv; /* socket info about our server */
    int mysocket;            /* socket used to listen for incoming connections */
    socklen_t socksize = sizeof(struct sockaddr_in);

    memset(&serv, 0, sizeof(serv));           /* zero the struct before filling the fields */
    serv.sin_family = AF_INET;                /* set the type of connection to TCP/IP */
    serv.sin_addr.s_addr = htonl(INADDR_ANY); /* set our address to any interface */
    serv.sin_port = htons(PORTNUMRCV);           /* set the server port number */    

    mysocket = socket(AF_INET, SOCK_STREAM, 0);

    //fcntl(mysocket, F_SETFD, O_NONBLOCK);

    /* bind serv information to mysocket */
    bind(mysocket, (struct sockaddr *)&serv, sizeof(struct sockaddr));

    /* start listening, allowing a queue of up to 1 pending connection */
    listen(mysocket, 1);

    int consocket = accept(mysocket, (struct sockaddr *)&dest, &socksize);
    while(consocket){
        //socklen_t fromlen;
        //fromlen = sizeof inet_ntoa(dest.sin_addr);
        char receivemsg[128];

        int rlen = recv(consocket, &receivemsg, 128, 0); //receive data
        int err = errno;
        //printf("recv error: %d\n", err);
        printf("Received string: %s from %s \n", receivemsg, inet_ntoa(dest.sin_addr));
        if(rlen > 0){
            receivemsg[rlen] = '\0';
            if(comparestr(KEY, receivemsg) == 1){
                printf("Local client\n");
                incrementor++;
            } else if(comparestr(KEY, receivemsg) == 2){
                printf("Remote client\n");
                incrementor--;
            } else {
                printf("Wrong key!\n");
            }
        } else {
            printf("Care!!!! Receiving: %d \n", rlen);
        }
        close(consocket);
        consocket = accept(mysocket, (struct sockaddr *)&dest, &socksize);
    }
    printf("Receive thread ended!\n");
    receive_thread_up = 0;
}

void *send_thread(){
    pthread_detach(pthread_self());

    struct sockaddr_in dest; /* socket info about the machine connecting to us */
    struct sockaddr_in serv; /* socket info about our server */
    int mysocket;            /* socket used to listen for incoming connections */
    socklen_t socksize = sizeof(struct sockaddr_in);

    memset(&serv, 0, sizeof(serv));           /* zero the struct before filling the fields */
    serv.sin_family = AF_INET;                /* set the type of connection to TCP/IP */
    serv.sin_addr.s_addr = htonl(INADDR_ANY); /* set our address to any interface */
    serv.sin_port = htons(PORTNUMSND);           /* set the server port number */

    mysocket = socket(AF_INET, SOCK_STREAM, 0);

    /* bind serv information to mysocket */
    bind(mysocket, (struct sockaddr *)&serv, sizeof(struct sockaddr));

    /* start listening, allowing a queue of up to 1 pending connection */
    listen(mysocket, 1);

    int consocket = accept(mysocket, (struct sockaddr *)&dest, &socksize);
    while(consocket){
        //printf("Incoming connection from %s - sending string\n", inet_ntoa(dest.sin_addr));
        int slen = send(consocket, KEY, 3*sizeof(KEY), 0); //send data
        if(slen>0)printf("Sent string: %s to %s \n", KEY, inet_ntoa(dest.sin_addr));
        else {
            printf("Care!!! Sending: %d \n", slen);
        }       
        close(consocket);
        consocket = accept(mysocket, (struct sockaddr *)&dest, &socksize);
    }
    printf("Send thread ended!\n");
    send_thread_up = 0;
}

在Java中是这样的:

代码语言:javascript
复制
public static int sendString(String str) throws IOException{
    System.out.println("Sending string: " + str);
    out.println(str);
    return 0;
}

public static String receiveString(){
    String s = " ";
    try {
        s = in.readLine();
    } catch (SocketException e) {
        System.out.println("Socket Exception: " + e);
    } catch (IOException e) {
        System.out.println("IOException on receive: " + e);
    }
    System.out.println("Received string: " + s);
    return s;
}
public static String reverseString(String str){
    String newStr = " ";
    newStr = new StringBuilder(str).reverse().toString();
    return newStr;
}

我的猜测是recv卡住了,所以我尝试添加

代码语言:javascript
复制
fcntl(mysocket, F_SETFD, O_NONBLOCK);

,在不起作用后,我对它进行了评论。也许使用UDP套接字?我可能会遇到消息未到达或不完整之类的问题。也欢迎提出改进我的代码的建议!

以下是C语言的输出:

代码语言:javascript
复制
Thread: No connection, waiting...
Sent string: I4mP4ssw0rd7 to 192.168.1.2
Received string: I4mP4ssw0rd7
 from 192.168.1.2
Local client
Sent string: I4mP4ssw0rd7 to 192.168.1.2
Thread: Local connection!
Received string: I4mP4ssw0rd7
 from 192.168.1.2
Local client
Sent string: I4mP4ssw0rd7 to 192.168.1.2
Sent string: I4mP4ssw0rd7 to 87.edited
Sent string: I4mP4ssw0rd7 to 87.edited
Sent string: I4mP4ssw0rd7 to 87.edited
Sent string: I4mP4ssw0rd7 to 87.edited
Sent string: I4mP4ssw0rd7 to 87.edited

下面是Java的输出:

代码语言:javascript
复制
03-18 22:52:45.831  13899-13899/willymatica.alarmapp1 I/System.out﹕ Connected!
03-18 22:52:49.375  13899-13920/willymatica.alarmapp1 I/System.out﹕ Connected locally!
03-18 22:52:49.585  13899-13920/willymatica.alarmapp1 I/System.out﹕ Received string: I4mP4ssw0rd7
03-18 22:52:54.900  13899-13920/willymatica.alarmapp1 I/System.out﹕ Sending string: I4mP4ssw0rd7
03-18 22:52:54.910  13899-13920/willymatica.alarmapp1 I/System.out﹕ Connected locally!
03-18 22:52:54.970  13899-13920/willymatica.alarmapp1 I/System.out﹕ Received string: I4mP4ssw0rd7
03-18 22:53:00.265  13899-13920/willymatica.alarmapp1 I/System.out﹕ Sending string: I4mP4ssw0rd7
03-18 22:53:00.285  13899-13920/willymatica.alarmapp1 I/System.out﹕ Connected locally!
03-18 22:53:00.315  13899-13920/willymatica.alarmapp1 I/System.out﹕ Received string: I4mP4ssw0rd7
03-18 22:53:05.631  13899-13920/willymatica.alarmapp1 I/System.out﹕ Sending string: I4mP4ssw0rd7
03-18 22:53:05.631  13899-13920/willymatica.alarmapp1 I/System.out﹕ Connected remotely!
03-18 22:53:05.851  13899-13920/willymatica.alarmapp1 I/System.out﹕ Received string: I4mP4ssw0rd7
03-18 22:53:11.266  13899-13920/willymatica.alarmapp1 I/System.out﹕ Sending string: 7dr0wss4Pm4I
03-18 22:53:11.286  13899-13920/willymatica.alarmapp1 I/System.out﹕ Connected remotely!
03-18 22:53:11.516  13899-13920/willymatica.alarmapp1 I/System.out﹕ Received string: I4mP4ssw0rd7
03-18 22:53:16.912  13899-13920/willymatica.alarmapp1 I/System.out﹕ Sending string: 7dr0wss4Pm4I
03-18 22:53:16.932  13899-13920/willymatica.alarmapp1 I/System.out﹕ Connected remotely!
03-18 22:53:17.162  13899-13920/willymatica.alarmapp1 I/System.out﹕ Received string: I4mP4ssw0rd7
03-18 22:53:22.547  13899-13920/willymatica.alarmapp1 I/System.out﹕ Sending string: 7dr0wss4Pm4I
03-18 22:53:22.567  13899-13920/willymatica.alarmapp1 I/System.out﹕ Connected remotely!
03-18 22:53:23.198  13899-13920/willymatica.alarmapp1 I/System.out﹕ Received string: I4mP4ssw0rd7
03-18 22:53:28.933  13899-13920/willymatica.alarmapp1 I/System.out﹕ Sending string: 7dr0wss4Pm4I
03-18 22:53:28.933  13899-13920/willymatica.alarmapp1 I/System.out﹕ Connected remotely!
03-18 22:53:29.113  13899-13920/willymatica.alarmapp1 I/System.out﹕ Received string: I4mP4ssw0rd7
EN

回答 1

Stack Overflow用户

发布于 2015-03-19 06:49:17

TCP是面向连接的。一旦建立了TCP连接,就会得到所谓的套接字对。套接字对是源ip地址和源端口以及目的ip地址和目的端口的组合。该连接由这4个参数唯一标识。

在整个会话期间,将使用相同的ip地址和端口。

因此,如果一个网络接口不再可用,就会出现问题,因为每个网络接口都会有一个ip地址,如果它不再可用,TCP连接将无法再选择不同的网络接口。

TCP不支持更改连接两端的IP地址。

这将需要相当长的时间来检测到存在问题。您认为仍然可以发送,但是,TCP将多次重新传输,最终您将看到发送失败。这甚至需要几分钟。根据您的套接字是否阻塞,您将注意到,在IP@已更改的错误条件下,send将阻塞。从TCP的角度来看,这就像断线一样。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29134010

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档