套接字通信的Connect()功能 [英] Connect() functionality of socket communication

查看:73
本文介绍了套接字通信的Connect()功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有关套接字通信的挂钟时间的问题.我有一个功能,可以找到在中央服务器上注册的服务器.我通过提取服务器的URL和端口号并通过像一个简单的TCP客户端一样尝试连接到它们,从而对该功能添加了一层网络检查.如果返回值大于0,则表示网络工作正常;否则,返回0.如果为-1,则表明网络已断开.

A question on the wallclock time of socket communication. I am having a function, which finds the servers registered at a central server. I am adding a layer of network check over this function by extracting the URL and port number of the servers and trying to connect to them by behaving like a simple TCP client. If the return value is greater than 0, then it means that the network is working fine; if -1, then the network is broken.

printf("--Checking for network connectivity--\n");
        for(size_t i = 0; i < serverOnNetworkSize; i++) {
           UA_ServerOnNetwork *server = &serverOnNetwork[i];
           A[i] = (char *)UA_malloc(server->discoveryUrl.length+1);
           memcpy(A[i],server->discoveryUrl.data,server->discoveryUrl.length);
           A[i][server->discoveryUrl.length] = 0;
           int length = strlen(A[i]);
          
          //discovery URLs are of the form : opc.tcp://hostname:port
          
          //new addition to extract port
            B[i] = A[i] + 10;
          //printf("Hostname: %s\n", B[i]);
            char *p = strrchr(B[i], ':');
            int port = strtoul(p+1, NULL, 10);
          //printf("%d\n",port);
            B[i][length-5]='\0';
          //printf("Hostname: %s\n", B[i]);
         

         
           //removing the port
           A[i][length-5]='\0';
           //without initial tcp binding
           C[i] = A[i] + 10;
          //printf("Hostname: %s\n", C[i]);

          // FIND IP OF THAT HOST
           if(i!=0){
            char ip_address[50];

            find_ip_address(C[i],ip_address);  
            socketCommunication(ip_address,C[i],port);
       }
}
          printf("--Checks done!--\n");

全球功能:

int find_ip_address(char *hostname, char *ip_address)
{
      struct hostent *host_name;
      struct in_addr **ipaddress;
      int count;
      if((host_name = gethostbyname(hostname)) == NULL)
      {
            herror("\nIP Address Not Found\n");
            return 1;
      }
      else
      {
            ipaddress = (struct in_addr **) host_name->h_addr_list;
            for(count = 0; ipaddress[count] != NULL; count++)
            {
                  strcpy(ip_address, inet_ntoa(*ipaddress[count]));
                  return 0;
            }
      }
      return 1;
}

void socketCommunication(char *ip_address,char *hostname, int port){
     int clientSocket,ret;
    struct  sockaddr_in serverAddr;
    char buffer[1024];
 
    
    clientSocket = socket(AF_INET,SOCK_STREAM,0);
    if(clientSocket<0){
        printf("Error in connection \n");
        exit(1);
    }

    //printf("Client socket is created\n");

    memset(&serverAddr,'\0',sizeof(serverAddr));

    serverAddr.sin_port = htons(port);
    serverAddr.sin_family=AF_INET;
    
    serverAddr.sin_addr.s_addr=inet_addr(ip_address);

    ret = connect(clientSocket,(struct sockaddr*)&serverAddr,sizeof(serverAddr));
    if(ret<0){
        printf("\nLOOKS LIKE NETWORK CONNECTION HAS FAILED. HAVE A LOOK AT    THE NETWORK CONNECTIVITY at host : %s\n",hostname);
        printf("\n----Updated Status Information----:\n");
        printf("Discovery URL : opc.tcp://%s:%d\n",hostname,port);
        printf("Status:CONNECTON TIMED OUT\n");
        printf("\n");
   }

要对此进行测试,我关闭了其中一台已注册服务器的网络.当我测量时间时,它会显示不一致的18秒,24、38秒等值.

To test this, I switch off the network from one of the registered servers. When I measure the time, it shows inconsistent values of 18seconds,24,38 seconds etc.

当我切换服务器的网络并运行我的应用程序时,会出现这些值.在同一应用程序的第二次运行中,该值有时会减小为2秒或1秒.

These values occur when I switch the network of the server and run my application. On a second run of the same application, the value reduces to 2seconds or 1 second sometimes.

输出:


LOOKS LIKE NETWORK CONNECTION HAS FAILED. HAVE A LOOK AT THE NETWORK CONNECTIVITY at host : o755-gksr

----Updated Status Information----:
Discovery URL : opc.tcp://o755-gksr:4841
Status:CONNECTON TIMED OUT

--Checks done!--
Time measured: 18 seconds.


再次尝试输出

--Checking for network connectivity--

LOOKS LIKE NETWORK CONNECTION HAS FAILED. HAVE A LOOK AT THE NETWORK CONNECTIVITY at host : o755-gksr

----Updated Status Information----:
Discovery URL : opc.tcp://o755-gksr:4841
Status:CONNECTON TIMED OUT

--Checks done!--
Time measured: 0 seconds.

我的问题是:为什么显示不一致的值?如果无法建立连接,是否应该不返回-1并迅速显示错误?是否有任何后台进程试图在停止之前建立有限次数的连接?

My question is : Why does it show inconsistent values? If the connection is not possible, should it not return -1 and show the error quickly? Is there any background process, which tries to establish the connection for a finite number of times before coming to a halt?

请让我知道.

关于,拉克山

推荐答案

connect()行为及其超时高度取决于底层网络.当目标计算机关闭时, connect()失败的原因还有很多.大多数情况下的错误是:

The connect() behavior and its timeouts highly depends on underlying network. There are more reasons why connect() fails when the target machine is down. Errors in most cases are:

  • ETIMEDOUT-这意味着客户端发送了SYN,但根本没有收到任何响应.这是TCP超时,可能会很长(分钟).
  • EHOSTUNREACH-这意味着本地ARP查询失败,或者客户端发送了SYN和ICMP错误,主机接收不到.几秒钟内检测到ARP查询失败.当ARP查询失败时,远程路由器通常会返回ICMP错误主机无法访问".

因此,如果服务器与客户端位于同一网络中,会发生什么情况:

So what happen in your case if the server is in the same network as your client :

  • 客户端在其ARP缓存中具有服务器的MAC地址.
  • 您"从注册的服务器之一关闭网络.".您可能从服务器断开电缆或类似的电缆.
  • 客户端呼叫连接.SYN直接从ARP缓存发送到MAC地址,在最坏的情况下,两分钟后,连接将以ETIMEDOUT返回.
  • 客户端删除ARP缓存中的条目.
  • 后续连接需要ARP解析.它可能在3个ARP请求(3秒)后失败,或者如果ARP缓存中的否定条目有效,则立即失败.它可能仅在几秒钟内有效.
  • The client has server's MAC address in its ARP cache.
  • You "switch off the network from one of the registered servers.". You probably disconnect a cable from the server or something like that.
  • The client calls connect. SYN is sent directly to the MAC address from the ARP cache and in worst case the connect returns with ETIMEDOUT after two minutes.
  • Client delete the entry in the ARP cache.
  • Subsequent connect needs ARP resolution. Either it fails after 3 ARP request (3 seconds) or it fails immediately if the negative entry in ARP cache is valid. It may be valid for a few seconds only.

如果服务器位于远程网络中,则情况类似.在这种情况下,远程路由器的ARP缓存有罪.如果远程路由器无法将IP地址解析为MAC地址,则它几乎立即发送ICMP主机不可达信息,但是如果远程路由器的ARP缓存中仍然有目标IP,则它会花费一些时间,这比它意识到缓存条目已过时且MAC地址不是可用.

If the server is in remote network then the situation is similar. The ARP cache of the remote router is guilty in this case. If the remote router cannot resolve IP address to MAC address then it send ICMP Host Unreachable almost immediately but if the remote router still has the destination IP in its ARP cache it takes some time than it realizes the cache entry is obsolete and MAC address is not available.

这篇关于套接字通信的Connect()功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆