使用setsockopt;当socket从另一侧关闭时,read返回0而不是-1

时间:2017-12-03 13:39:31

标签: c linux sockets tcp

我使用TCP套接字连接设备。我关闭连接的一侧 - 服务器端。我正在使用setsockopt和timeout。根据我的理解,在这种情况下,客户端套接字上的Aread调用应返回-1。但它返回0.我需要修改什么吗? 粘贴下面的客户端代码。

void* socketClientLoop(void* arg)

{
    //struct socketArgs* sockArg = (struct socketArgs *)arg;
    char server_address[20] , *strtokResult;
    strcpy(server_address,"192.168.43.217"/*sockArg->server_address*/); 
    printf("\nsocket : server address in clientLoop = %s\n",server_address);
    struct sockaddr_in addr = { 0 };
    int s, status, distance;
    int distanceFromSocket = 0;//sockArg->distance;
    char gpsMessage[128], dist[16];
    int flag = true, writeFlag = false;

    struct timeval tv;

    while(true)
    {
       printf("socket : loop started\n"); 

        flag = true;
        // allocate a socket
       printf("socket : loop started1\n"); 
        s = socket(AF_INET, SOCK_STREAM, 0);
       printf("socket : loop started2\n"); 

        if(s<0) perror("socket error in client loop");

        // set the connection parameters (who to connect to)
        addr.sin_family = AF_INET;
        addr.sin_port = htons(5000);
        if(inet_pton(AF_INET, server_address, &addr.sin_addr)<=0)
        {
            printf("\n socket : inet_pton error occured\n");
            return 0;
        } 


        tv.tv_sec = 15; // 30 seconds
        tv.tv_usec = 0; // microsecs, set to 0 (or ...)
        setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv,sizeof(struct timeval));

        // connect to server
        status = connect(s, (struct sockaddr *)&addr, sizeof(addr));

        if(status<0) perror("socket status  error in client loop");

        // send a message
        if( status == 0 ) {
            while(flag)
            {
                sleep(5);
                memset(gpsMessage,0,sizeof(gpsMessage));
                status = read(s,gpsMessage, 128);
                if(!strncmp(gpsMessage,"connected",9)) writeFlag = true;
                else writeFlag = false;
                strtokResult = strtok(gpsMessage,":");
                if(strtokResult) 
                {
                    strtokResult = strtok(0,":");
                    if(strtokResult) 
                    {
                        strcpy(dist,strtokResult);
                        sscanf(dist,"%d",&distance);
                    }
                }
                printf("dist = %d\n", distance);
                printf("socket : clientLoop did not exited\n");
                if(distance == 2*distanceFromSocket)
                {
                    /*pthread_mutex_lock(&fill_mutex); 
                    pthread_cond_signal(&cond_var);
                    pthread_mutex_unlock(&fill_mutex);*/
                }
                if(writeFlag)
                {
                    socketPrepareMessageToSend(gpsMessage);
                    status = write(s,gpsMessage , strlen(gpsMessage));
                    //if(status < 0) flag=false;
                }
                //strcpy(gpsMessage,"No Ring");
                status = read(s,gpsMessage, 128);
                printf("bytes_read %d \n",status);
                if(status < 0)
                {
                    printf("set loopflag\n");
                    flag=false;
                    writeFlag=false;
                }
                else
                {
                     writeFlag=true;
                    printf("ring  no ring = %s\n",gpsMessage);
                    if(!strcmp(gpsMessage,"Ring"))
                    {
                        printf("SOCKET RING\n");
                        system("espeak -ven+f3 -k5 -s150 \"I've just picked up a fault in the AE35 unit\"");
                    }  
                    else printf("wrongoption\n");
                }
            }
        }

        if( status < 0 ) perror("uh oh");
        printf("socket : clientLoop exited\n");
        close(s);
        printf("socket : end of loop\n");
    }
}

1 个答案:

答案 0 :(得分:3)

当套接字从另一侧关闭时,它表示文件结束,并且读取调用将返回0. 是正确的行为。

参见: https://linux.die.net/man/2/read