问题标签 [berkeley-sockets]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
sockets - 有人可以很好地解释非阻塞套接字的“发送”行为吗?
我现在至少阅读了 10 次文档,并且还阅读了大约 10 个代码片段和完整的程序,其中非阻塞套接字用于发送数据。问题是有些教程要么是为初学者准备的(Beejs fi),要么是他们的假设相当草率;那些并不复杂的是专门的代码示例,没有解释他们为什么要做他们所做的事情。send
在我看来,即使是 SO 知识库也不能详尽地涵盖整个行为范围。我所追求的是关于 fe 的详细信息:
- 返回代码 0 究竟表示什么,是否值得检查
errno
,还是应该放弃连接而不进行进一步调查? - 获得负返回值是否保证关闭连接变坏,或者只有这样,除非
errno
isEWOULDBLOCK
,EAGAIN
或EINTR
(...others) ? errno
返回值是否值得检查> 0
?显然,该值表示“发送”的数据量(在引号中,因为它确实是一个很长的过程,对),但由于套接字是非阻塞的,这是否意味着可以立即发出另一个调用,或者errno
再次取决于,应该等待下一个发送时机(使用 select/poll/epoll)?- 基本上,是否首先检查返回值,然后才检查
errno
值?或者可能在每次调用时send
设置,无论如何都返回值?errno
这将使错误检查更容易一些...... - 如果得到
EINTR
,程序要采取的良好、稳健的行为是什么?只需记录状态并在下一次发送时重试,例如使用EWOULDBLOCK
andEAGAIN
? - 是否同时 检查
EWOULDBLOCK
和EAGAIN
?我们可以相信两者具有相同的价值,还是取决于实现? - 是否
send
返回EMSGSIZE
流套接字?如果不是,那么缓冲区大小不会太大,对吗? - 返回值本身可以等于任何一个已知的错误代码吗?
如果你能提供一个健壮的非阻塞发送代码的例子,那将不胜感激。
c - 确定 (S)NTP 数据包的目标时间戳?
我正在尝试使用 Berkeley 套接字 API 在 C 中创建一个简单的 SNTP 客户端,但是我无法从响应消息中计算调整后的时间。我从RFC2030得到这个。
当收到服务器回复时,客户端根据其NTP时间戳格式的时钟确定一个Destination Timestamp变量作为到达时间。下表总结了四个时间戳。
- Originate Timestamp (T1):客户端发送的时间请求
- Receive Timestamp (T2):服务器接收到的时间请求
- Transmit Timestamp (T3):服务器发送的时间回复
- 目标时间戳(T4):客户端收到的时间回复
据我所知,我可以通过获取客户的时间并将时间偏移量t添加到它来计算调整后的当前时间,时间偏移量定义为
我需要知道T4才能进行此计算,但这不是数据包消息的一部分。我怎样才能获得这个时间戳?
sockets - Tcp 套接字读取总是阻塞
我有一个客户端 TCP 套接字,它每五秒写入几个字节,服务器立即回显这些字节。
Connect()和write()工作得很好,我在 IP 层有一个回调,通知我服务器的回声。这在发送之间可靠地发生。
但我无法从套接字读取回声。
我尝试使用select()来通知我传入的回声。奇怪的是,我的回调直到我关闭套接字才被调用,此时它被连续调用。然而,对于这些调用中的每一个,read()返回 -1/WOULD_BLOCK。
当 IP 层通知我传入数据时,我的第二种方法异步调用read() 。同样,read()只返回 -1/WOULD_BLOCK。我意识到read()可以将数据传输到套接字层,但希望它只是意味着在下一次写入后读取更多内容。
我倾向于认为我在某种程度上滥用了 API,因为我是一个 IP/sockets 菜鸟,并且选择方法表现得如此奇怪。
这不太可能是一个愚蠢的错误,因为几乎相同的代码路径非常适合 UDP 模式。唯一的区别:对于 UDP,我使用 DATAGRAM 模式、sendto() 和 recvfrom()。对于 TCP,我使用 STREAM 模式、write() 和 read()。
c - 从套接字读取直到某个字符在缓冲区中
我正在尝试从套接字读取到缓冲区,直到使用read(fd, buf, BUFFLEN)
.
例如,套接字将在一次读取调用中接收由空行分隔的两批信息。
是否可以将读取调用置于循环中,以便在到达此空白行时停止,然后如果需要,它可以稍后读取其余信息?
c++ - 在 C/C++ 中获取网关地址
我ioctl()
用来设置网关地址(SIOCADDRT
在RTF_GATEWAY
标志中)。
检索它的标准 ioctl 例程是什么?
c++ - TCP 连接已接受,但写入数据会导致它使用过时的连接
服务器 (192.168.1.5:3001) 运行 Linux 3.2,设计为一次只接受一个连接。客户端 (192.168.1.18) 正在运行 Windows 7。连接是无线连接。这两个程序都是用 C++ 编写的。
它在 10 个连接/断开周期中有 9 个效果很好。根据 Wireshark(见截图)的说法,第十个(随机发生)连接让服务器接受连接,然后当它稍后实际写入它时(通常是 30 多秒后),看起来它正在写入一个旧的陈旧连接,带有客户端已 FIN(不久前)但服务器尚未 FIN 的端口号。所以客户端和服务器连接似乎不同步——客户端建立新连接,服务器尝试写入前一个连接。一旦进入这种断开状态,每个后续的连接尝试都会失败。可以通过超出最大无线范围半分钟来启动断开状态(如之前 10 次中有 9 次这样有效,但有时会导致断开状态)。
屏幕截图中的红色箭头表示服务器何时开始发送数据(Len != 0),即客户端拒绝它并向服务器发送 RST 的时间点。右边缘下方的彩色点表示使用的每个客户端端口号的单一颜色。请注意在该颜色的其余点之后出现的一两个点如何很好地出现(并注意时间列)。
问题看起来像是在服务器端,因为如果您终止服务器进程并重新启动,它会自行解决(直到下次发生)。
希望代码不会太不寻常。我将listen()中的队列大小参数设置为0,我认为这意味着它只允许一个当前连接而没有挂起的连接(我尝试了1,但问题仍然存在)。在代码中显示“//错误”的跟踪打印中,没有任何错误出现。
因此,在 accept() 调用(假设这正是发送 SYN 数据包的时间点)和 write() 调用之间的某个地方,客户端的端口被更改为先前使用的客户端端口。
所以问题是:服务器怎么会接受一个连接(并因此打开一个文件描述符),然后通过以前的(现在是陈旧的和死的)连接/文件描述符发送数据?它是否需要在缺少的系统调用中提供某种选项?
c - 带有 BSD/POSIX 套接字的可移植 IPv6 连接
我需要连接到 IPv6 地址。这不是硬编码的。我将以字节形式(char *)获取 IPv6 地址,并且不会使用 DNS 检索它们(getaddrinfo 不走运)。问题是,我应该填写的 sockaddr_in6 结构在不同的平台上是完全不同的。
如果有一种很好的便携方式可以从原始地址字节连接到 IPv6 地址?
我还应该提到我也在使用 libevent。
c - Berkeley 套接字:connect() 返回 -1 且 errno 设置为 ENOENT
我有这个代码:
IPv6 设置为 false,IP 设置为 ::ffff:127.0.0.1(IPv4 环回地址),端口号设置为 45562,res 设置为 -1,errno 设置为 ENOENT (2)。为什么会这样?
我所在的平台是 OSX Mountain Lion。我正在使用带有 libevent 版本“2.0.19-stable”的套接字。
谢谢你。
linux - 在linux中绑定wifi接口
我正在开发一个具有 LAN 和 WIFI 接口的基于 linux 的系统。但我必须只将我的套接字与 wifi 接口绑定。有什么通用的方法可以找出哪个接口是wifi,所以我可以用它来装我的插座吗?如果没有,我是否可以绑定并接收来自两个接口的请求?
目前,我正在使用 INADDR_ANY 进行绑定。我知道如何与 eth0 等特定接口绑定,但我找不到任何方法来确定 eth0 是否是 wifi 接口;至少在 C 中。使用 INADDR_ANY 我将接收发送到任何接口的数据包,但我的发送可能会尝试通过 LAN 接口发送它;这不是我想要的。
c - 伯克利套接字通信,发送和接收结构
我有一个任务,我要为游戏实现一个得分服务器。游戏完成后,游戏将发送()玩家姓名(char *name)和得分(int score)到服务器进行注册,receive(),服务器将发送回5个最高分。
我们将使用 Berkeley 套接字和 C。在阅读和研究了一些示例之后,我只能找到只发送单个变量的示例。
通常做什么?发送每个变量(名称和分数)是单独的 write() 函数,还是创建一个包含两个变量的结构?
在阅读了Beej 的网络编程指南之后,我遇到了我必须考虑的字节顺序(大/小端序)问题,这在第7.4 节序列化 - 如何打包数据下显示,除了在所有示例代码包中它们浮动和单个变量,有没有办法打包整个结构?
还有一节7.5 Sone of Data Encapsulation涉及创建一个描述客户端和服务器如何通信的协议,对我来说,这看起来更像一个结构,我不会做,但是没有显示原理的代码。
简而言之:我想在服务器和客户端之间建立稳定的通信,在这里我交换的不仅仅是单个变量,