gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 17:34:07 32 4
gpt4 key购买 nike

对于一个类(class)项目,我们被指示使用 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() 函数中。如果您在 socket()connect() 调用之间插入这段代码,它应该可以解决问题。

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

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

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

关于c - 使用Winsock2和C缩短TCP连接的等待时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23503392/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com