2016年6月23日 星期四

0623 socket 的connect 如何增加time out 屬性

將socket 設定為noblock 即可
即增加下方藍色字體部分

自製範例:
//利用socket 測試是否已經連上線
#include <sys/socket.h>
#include <netinet/tcp.h>
#include <netinet/in.h>
#include <unistd.h>
#include <netdb.h>       // for gethostbyname()

int checkRobotLinkState()
{
    return robotLink_state;
}
void startRobotLinkFun()
{
    robotLink_state=robotlink_conning;
    threadcv.notify_one(); //啟動thread
    
}

void robotSocketLink()
{
    int sock,ret;
    struct sockaddr_in server;
    struct hostent* entp = NULL;
    log("00.Construct Client... start init socket\n");
    // Create socket
    if( (sock = socket(PF_INET, SOCK_STREAM, 0))<0 )
    {
        log("socket() failed with error \n");
        robotLink_state= robotlink_ER1;
        return;
    }
    log("01.socket init...check TCP/IP\n");
    
    // Disable Nagel's algorithm for lower latency
    int yes = 1;
    if(setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &yes,
                  sizeof(int)) == -1)
    {
        log("failed to enable TCP_NODELAY - setsockopt failed");
        robotLink_state= robotlink_ER2;
        return;
    }
    log("02.TCP/IP Ready...wait check IP\n");
    // Construct server address
    memset(&server, 0, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_port = htons(6665);
    
    // Get host by name
    entp = gethostbyname("192.168.30.1");
    if (entp == NULL)
    {
        log("gethostbyname() failed with error \n");
        robotLink_state= robotlink_ER3;
        return;
    }
    //BOB ADD 設定socket nonblock 避免time out 過久
    fcntl(sock, F_SETFL, O_NONBLOCK);
    fd_set set;
    FD_ZERO(&set);
    FD_SET(sock, &set);
    
    log("03.check robot IP OK...wait connect\n");
    assert(entp->h_length <= sizeof (server.sin_addr));
    memcpy(&(server.sin_addr), entp->h_addr_list[0], entp->h_length);
    
    // Connect
     ret = connect(sock, (struct sockaddr*)&server, sizeof(server));
    if (ret < 0)
    {
        if ( errno != EINPROGRESS )
        {
            printf("connect call on [%s:%d] failed! \n", "192.168.30.1", 6665);
            robotLink_state= robotlink_ER4;
            return;
            
        }
    }
    log("04.connect start...select...\n");
    struct timeval  timeout;
    timeout.tv_sec = 3; //搜尋3
    timeout.tv_usec = 0;
    int status = select(sock+1, &set, NULL, NULL, &timeout);
    if(status==1)
    {
        robotLink_state= robotlink_LinkOK;
        log("end. connect OK \n");
        
    }
    else
    {
        robotLink_state= robotlink_ER5;
        log("05. select time out(3 sec.) \n");
    }


}




==================================



網路 成功範例如下
http://stackoverflow.com/questions/14254061/setting-time-out-for-connect-function-tcp-socket-programming-in-c-breaks-recv

int sock;
struct sockaddr_in addr;
int connectWithServer
{

    int status;

    struct timeval  timeout;
    timeout.tv_sec = 10;
    timeout.tv_usec = 0;

    addr.sin_port = htons(port);
    sock = socket (AF_INET,SOCK_STREAM,0);
    inet_pton(AF_INET,serverIP,&addr.sin_addr);

    fd_set set;
    FD_ZERO(&set);
    FD_SET(sock, &set);

    fcntl(sock, F_SETFL, O_NONBLOCK);

    if ( (status = connect(sock, (struct sockaddr*)&addr, sizeof(addr))) == -1)
    {
        if ( errno != EINPROGRESS )
            return status;

    }
    status = select(sock+1, NULL, &set, NULL, &timeout);

    return status;
}


long int receiveResponse (void *response , unsigned int length)
{
    socklen_t sockLen = sizeof(struct sockaddr);
    long int received = recvfrom(sock, response, length, 0,(struct sockaddr *)&addr,  &sockLen);
    printf("Received %ld bytes...  err %d\n",received, errno);

    return received;

}

沒有留言:

張貼留言

cocos2dx-lua 建立滑鼠監聽

重要關鍵字  EVENT_MOUSE_SCROLL addEventListenerWithSceneGraphPriority      if IsPc() then --建立滑鼠監聽         local listener = cc.EventListenerMouse...