繁体   English   中英

使用Winsock2和C缩短TCP连接的等待时间

[英]Shortening wait time for TCP connection using Winsock2 and C

对于课程项目,我们被指示使用Winsock2创建简单的程序。 我创建了一个开始的echo程序,现在我正在尝试为该程序实现一种在房间内查找主机本身的方法。 房间位于一个专用网络192.168.xxx.xxx上,子网上升了10,并且可以运行服务器的计算机在每个子网中分别为50、51和52。 我打算做的一个简单实现就是尝试连接到每台计算机(如果可以),它就是服务器。 不是最好的解决方案,但它仍然使用Winsock2,并且对我有用。

SOCKET connectsock(const char *host, const char *service, const char *transport )
{
struct hostent  *phe;   /* pointer to host information entry    */
struct servent  *pse;   /* pointer to service information entry */
struct protoent *ppe;   /* pointer to protocol information entry*/
struct sockaddr_in sin; /* an Internet endpoint address     */
int s, type;    /* socket descriptor and socket type    */

while (1)
{
    memset(&sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;

    /* Map service name to port number */
    if ( pse = getservbyname(service, transport) )
        sin.sin_port = pse->s_port;
    else if ( (sin.sin_port = htons((u_short)atoi(service))) == 0 )
        errexit("can't get \"%s\" service entry\n", service);

    /* Map host name to IP address, allowing for dotted decimal */
    if ( phe = gethostbyname(host) )
        memcpy(&sin.sin_addr, phe->h_addr, phe->h_length);
    else if ( (sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE)
        errexit("can't get \"%s\" host entry\n", host);

    /* Map protocol name to protocol number */
    if ( (ppe = getprotobyname(transport)) == 0)
        errexit("can't get \"%s\" protocol entry\n", transport);
    /* Use protocol to choose a socket type */
    if (strcmp(transport, "udp") == 0)
        type = SOCK_DGRAM;
    else
        type = SOCK_STREAM;

    /* Allocate a socket */
    s = socket(PF_INET, type, ppe->p_proto);
    if (s == INVALID_SOCKET)
        errexit("can't create socket: %d\n", GetLastError());

    /* Connect the socket */

    if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) == SOCKET_ERROR)
    {
        printf("can't connect to %s.%s: %d\n", host, service, GetLastError());
        host = "localhost";
    }
    else
        break;
}
return s;

}

此循环工作正常,只需连接到第一个IP地址192.168.10.50,然后如果它拉出错误,就连接到下一个主机,如果另一个错误,它将尝试第三个主机,依此类推,直到连接为止。成功。 由于我仍仅测试程序,因此在第一次失败后,我只能将其重定向到连接到本地主机。

它按原样完美运行,唯一的问题是在类内,没有延迟。 因此,连接(如果可用)发生十分之一秒。 默认情况下,该程序将尝试连接到第一台计算机,并且将无法连接,但是它会坐下来等待5秒钟以做出响应,然后再切换到下一个主机。

由于它是封闭网络中的一个小型程序,因此将等待时间缩短至半秒应该没有问题,但是我的问题是如何?

有可能,如果没有,我该怎么做才能纠正它? 有没有更有效的方法来使主机找到可以移动的服务器? 服务器将更换计算机。

如果您使用非阻塞套接字,则应该能够使用单个线程有效地执行此扫描。 为了做到这一点,您将使用ioctlsocket()函数。

您可以很容易地connectsock()其放入您的connectsock()函数。 如果您在socket()connect()调用之间socket()此代码块,它应该可以解决问题。

static u_long iMode=1; 
ioctlsocket(s,FIONBIO,&iMode);

这将使connectsock()创建的所有套接字都变为非阻塞状态。 这意味着这些套接字上的所有操作将立即返回,而不管是否有等待读取或写入的数据。

您可以根据需要触发任意数量的connectsock()调用,并仅跟踪在数组中创建的所有套接字。 如果尝试立即读取或写入套接字,则尝试可能会失败。 但是,如果等待几毫秒,则可能会建立套接字,并且尝试将成功。 然后,您可以通过任何可返回错误代码的winsock函数运行它们,如果错误代码不是SOCKET_ERROR ,则表示套接字的另一端有一个客户端。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM