gpt4 book ai didi

sockets - SCTP:成功connect()调用后,SCTP套接字的sctp status.sstate值应该是什么?

转载 作者:行者123 更新时间:2023-12-03 12:03:51 25 4
gpt4 key购买 nike

我正在尝试通过SCTP连接到远程对等设备(除了通过套接字和ping连接到它之外,我没有目录访问权限)。假设我已成功连接,那么如果我尝试调用getsocktopt(),则sctp_status.sstate的值应该是多少?根据sctp.h,我的名字是SCTP_COOKIE_ECHOED(3)。这是正确的吗?不应该是SCTP_ESTABLISHED吗?

因为我尝试使用以下代码向远程对等方发送消息:

ret = sctp_sendmsg (connSock, (void *) data, (size_t) strlen (data), (struct sockaddr *) &servaddr, sizeof (servaddr), 46, 0, 0, 0, 0);

它返回了我尝试发送的字节数。然后,当我 try catch 是否有任何响应时:
ret = sctp_recvmsg (connSock, (void *) reply, sizeof (reply), NULL,
NULL, NULL, &flags);

它返回带有ECONNRESET(104)的错误号的-1。我的代码或流程中可能出现的错误是什么?我错过了什么?

在此先感谢您的回答。会很高兴地意识到这一点。 :)

更新:下面是我连接到远程对等方的客户端代码。我实际上使用的是一个节点附加组件,因为节点中不完全支持SCTP。使用lksctp-tools包包括头文件。
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/sctp.h>
#include <arpa/inet.h>
#include <signal.h>
#define MAX_BUFFER 1024

int connSock = 0;

int connect(char host[], int port, char remote_host[], int remote_port, int timeout) {

int ret, flags;
fd_set rset, wset;
struct sockaddr_in servaddr;
struct sockaddr_in locaddr;
struct sctp_initmsg initmsg;
struct timeval tval;
struct sctp_status status;
socklen_t opt_len;

errno = 0;

connSock = socket (AF_INET, SOCK_STREAM, IPPROTO_SCTP);
flags = fcntl(connSock, F_GETFL, 0);
fcntl(connSock, F_SETFL, flags | O_NONBLOCK);

if (connSock == -1)
{
return (-1);
}

memset(&locaddr, 0, sizeof(locaddr));
locaddr.sin_family = AF_INET;
locaddr.sin_port = htons(port);
locaddr.sin_addr.s_addr = inet_addr(host);

ret = bind(connSock, (struct sockaddr *)&locaddr, sizeof(locaddr));

if (ret == -1)
{
return (-1);
}

memset (&initmsg, 0, sizeof (initmsg));
initmsg.sinit_num_ostreams = 5;
initmsg.sinit_max_instreams = 5;
initmsg.sinit_max_attempts = 10;
ret = setsockopt(connSock, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(initmsg));

if (ret == -1)
{
return (-1);
}

memset (&servaddr, 0, sizeof (servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons (remote_port);
servaddr.sin_addr.s_addr = inet_addr (remote_host);

if((ret = connect (connSock, (struct sockaddr *) &servaddr, sizeof (servaddr))) < 0)
if (errno != EINPROGRESS)
return (-1);

if (ret == 0) {
fcntl(connSock, F_SETFL, flags);
return 0;
}

FD_ZERO(&rset);
FD_SET(connSock, &rset);
wset = rset;
tval.tv_sec = timeout;
tval.tv_usec = 0;

ret = select(connSock+1, &rset, &wset, NULL, timeout ? &tval : NULL);

if (ret == 0) {
close(connSock);
errno = ETIMEDOUT;
return(-1);
}
else if (ret < 0) {
return(-1);
}

fcntl(connSock, F_SETFL, flags);

opt_len = (socklen_t) sizeof(struct sctp_status);
getsockopt(connSock, IPPROTO_SCTP, SCTP_STATUS, &status, &opt_len);

printf ("assoc id = %d\n", status.sstat_assoc_id);
printf ("state = %d\n", status.sstat_state);
printf ("instrms = %d\n", status.sstat_instrms);
printf ("outstrms = %d\n", status.sstat_outstrms);

return 0;
}

int sendMessage(char remote_host[], int remote_port, char data[]) {

int ret, flags;
struct sockaddr_in servaddr;
char reply[1024];

errno = 0;

memset (&servaddr, 0, sizeof (servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons (remote_port);
servaddr.sin_addr.s_addr = inet_addr (remote_host);

printf("\nSending %s (%li bytes)", data, strlen(data));

ret = sctp_sendmsg (connSock, (void *) data, (size_t) strlen (data),
(struct sockaddr *) &servaddr, sizeof (servaddr), 46, 0, 0, 0, 0);

if (ret == -1)
{
printf("\nError sending errno(%d)", errno);
return -1;
}
else {
ret = sctp_recvmsg (connSock, (void *) reply, sizeof (reply), NULL,
NULL, NULL, &flags);

if (ret == -1)
{
printf("\nError receiving errno(%d)", errno);
return -1;
}
else {
printf("\nServer replied with %s", reply);
return 0;
}
}
}

int getSocket() {

return connSock;
}

我不知道在错过连接之前是否需要先设置重要的东西。我从不同来源获得了摘要,因此非常困惑。

另一个更新,这是执行该代码时的tshark日志:
3336.919408  local  -> remote SCTP 82 INIT
3337.006690 remote -> local SCTP 810 INIT_ACK
3337.006727 local -> remote SCTP 774 COOKIE_ECHO
3337.085390 remote -> local SCTP 50 COOKIE_ACK
3337.086650 local -> remote SCTP 94 DATA
3337.087277 remote -> local SCTP 58 ABORT
3337.165266 remote -> local SCTP 50 ABORT

here的详细tshark日志。

看起来远程发送了它的COOKIE_ACK块,但是我的客户端未能将其状态设置为ESTABLISHED(我仔细检查了sstate的值3 here)。

最佳答案

如果关联设置过程完成,则状态应为SCTP_ESTABLISHED。 SCTP_COOKIE_ECHOED表示关联尚未完全建立。这意味着始发端(在这种情况下,您的本地主机)已发送(一次或多次)COOKIE_ECHO块,而COOKIE_ACK尚未从远端确认该块。

您可以在这种状态下发送消息(SCTP会简单地对其进行缓冲,直到获得COOKIE_ACK并稍后重新发送)。

根据您提供的信息很难说出什么地方出了问题。在此阶段,可能有必要深入研究Wireshark跟踪,以查看远程方在您的COOKIE_ECHO上进行了答复。

另外,如果您可以共享可能有助于确定根本原因的客户端/服务器端代码。

更新#1:
还应注意,应用程序可以自行中止关联(例如,如果未在该服务器上配置此关联)。如果您尝试连接到随机服务器(而不是您的特定服务器),则完全有可能,并且在您的情况下确实有意义。在这种情况下,您一方的关联状态为COOKIE_ECHOED,因为COOKIE_ACK尚未到达(仅是比赛条件)。就像我之前说过的,SCTP在这种状态下愉快地接受您的数据,并仅对其进行缓冲,直到接收到COOKIE_ACK。即使在应用程序在accept()中接收到执行控制之前,远程端的SCTP也会立即发送COOKIE_ACK。如果应用程序决定以不友好的方式终止关联,它将发送ABORT(这是Wireshark跟踪中的第一个ABORT)。您的一方尚未收到此ABORT,并发送DATA块。由于远程端认为此关联已终止,因此它无法处理DATA块,因此将其视为突发事件(请参阅RFC 4960第8.4章),并发送另一个t-bit设置为1的ABORT。
我想这就是您的情况。您只需查看wireshark轨迹即可轻松确认它。

关于sockets - SCTP:成功connect()调用后,SCTP套接字的sctp status.sstate值应该是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43625026/

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