- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
过去几天我正在研究套接字(用 C 语言,以前没有套接字编程经验)。实际上我必须在树莓派上收集WiFi数据包,进行一些处理,并且必须通过套接字将格式化信息发送到另一个设备(两个设备都连接在网络中)。
我面临的挑战是通过套接字接收数据时。
发送数据时,发送端通过套接字发送成功,但接收端有时会收到一些垃圾或以前的数据。
在发送方(客户端):
int server_socket = socket(AF_INET, SOCK_STREAM, 0);
//connecting to the server with connect function
send(server_socket, &datalength, sizeof(datalength),0); //datalength is an integer containing the number of bytes that are going to be sent next
send(server_socket, actual_data, sizeof(actual_data),0); //actual data is a char array containing the actual character string data
在接收端(服务器端):
int server_socket = socket(AF_INET, SOCK_STREAM, 0);
//bind the socket to the ip and port with bind function
//listen to the socket for any clients
//int client_socket = accept(server_socket, NULL, NULL);
int bytes;
recv(client_socket, &bytes, sizeof(bytes),0);
char* actual_message = malloc(bytes);
int rec_bytes = recv(client_socket, actual_message, bytes,0);
*上面的代码行不是实际的代码行,但流程和过程类似(带有异常处理和注释)。
有时,我可以快速获取所有数据包的实际数据(没有任何错误和数据包丢失)。但有时字节(发送的整数来告诉下一个事务的字节流的大小)被作为垃圾值接收,所以我的代码在那时就被破坏了。有时,我在接收端收到的字节数小于预期的字节数(从接收到的整数字节数得知)。因此,在这种情况下,我会检查该条件并检索剩余的字节。
实际上,数据包到达的速率非常高(不到一秒大约1000 个数据包,我必须剖析、格式化并通过套接字发送)。我正在尝试不同的想法(使用 SOCK_DGRAMS 但这里有一些数据包丢失,在事务之间插入一些延迟,为每个数据包打开和关闭一个新套接字,在接收数据包后添加确认)但它们都不满足我的要求(快速传输0 丢包的数据包数)。
请建议一种通过套接字快速发送和接收不同长度数据包的方法。
最佳答案
我发现一些主要问题:
我认为您的代码忽略了 send
函数中缓冲区已满的可能性。
在我看来,您的代码忽略了
(没关系,我刚刚看到了对此的新评论)recv
收集部分数据的可能性。
换句话说,您需要管理send
的用户态缓冲区并处理recv
中的碎片。
代码使用 sizeof(int)
,在不同的机器上可能有不同的长度(也许使用 uint32_t
代替?)。
代码不会在网络字节顺序之间进行转换。这意味着您发送的是 int 的内存结构,而不是可以由不同机器读取的整数(有些机器向后存储字节,有些机器向前存储字节,有些机器混合匹配)。
请注意,当您使用 TCP/IP 发送较大数据时,它将被分成较小的数据包。
这取决于 MTU 网络值(在野外通常以约 500 字节运行,在家庭网络中通常以约 1500 字节运行)。
要处理这些情况,您可能应该使用事件网络设计而不是阻塞套接字。
考虑通过与此类似的方式路由发送
(如果您要使用阻塞套接字):
int send_complete(int fd, void * data, size_t len) {
size_t act = 0;
while(act < len) {
int tmp = send(fd, (void *)((uintptr_t)data + act), len - act);
if(tmp <= 0 && errno != EWOULDBLOCK && errno != EAGAIN && errno != EINTR)
return tmp; // connection error
act += tmp;
// add `select` to poll the socket
}
return (int)act;
}
对于 sizeof
问题,我会将 int
替换为特定字节长度的整数类型,例如 int32_t
。
更多细节
请注意,单独发送整数并不能保证它会被单独接收或整数本身不会被分段。
send
函数写入套接字的系统缓冲区,不写入网络(就像 recv
从可用缓冲区读取数据并不是来自电线)。
您无法控制碎片发生的位置或 TCP 数据包的打包方式(除非您实现自己的 TCP/IP 堆栈)。
我相信您很清楚“垃圾”值是服务器发送的数据。这意味着代码不是读取您发送的整数,而是读取另一条数据。
这可能是消息边界对齐的问题,由不完整的读取
或不完整的发送
引起。
附注
我会考虑在 TCP/IP 层之上使用 Websocket 协议(protocol)。
这保证了二进制数据包 header 可以与不同的 CPU 架构(字节顺序)配合使用,并提供更广泛的客户端连接(例如与浏览器连接等)。
它还将解决您遇到的数据包对齐问题(不是因为它不存在,而是因为它已在您将采用的任何 Websocket 解析器中得到解决)。
关于c - 通过 C 语言的套接字快速接收不同长度数据包的连续流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46404245/
我使用下拉菜单提供一些不同的链接,但我希望这些链接在同一选项卡中打开,而不是在新选项卡中打开。这是我找到的代码,但我对 Javascript 非常缺乏知识 var urlmenu = docume
我对 javascript 不太了解。但我需要一个垂直菜单上的下拉菜单,它是纯 JavaScript,所以我从 W3 复制/粘贴脚本:https://www.w3schools.com/howto/t
我已经坐了 4 个小时,试图让我的导航显示下 zipper 接垂直,但它继续水平显示它们。我无法弄清楚为什么会发生这种情况或如何解决它。 如果有人能告诉我我做错了什么,我将不胜感激。我有一个潜移默化的
我正在尝试创建选项卡式 Accordion 样式下拉菜单。我使用 jQuery 有一段时间了,但无法使事件状态达到 100%。 我很确定这是我搞砸的 JS。 $('.service-button').
对于那些从未访问过 Dropbox 的人,这里是链接 https://www.dropbox.com/ 查看“登录”的下拉菜单链接。我如何创建这样的下 zipper 接? 最佳答案 这是 fiddle
我正在制作一个 Liferay 主题,但我在尝试设计导航菜单的样式时遇到了很多麻烦。我已经为那些没有像这样下拉的人改变了导航链接上的经典主题悬停功能: .aui #navigation .nav li
如果您将鼠标悬停在 li 上,则会出现一个下拉菜单。如果您将指针向下移至悬停时出现的 ul,我希望链接仍然带有下划线,直到您将箭头从 ul 或链接移开。这样你就知道当菜单下拉时你悬停在哪个菜单上。 知
我有一个带有多个下拉菜单的导航栏。因此,当我单击第一个链接时,它会打开下拉菜单,但是当我单击第二个链接时,第一个下拉菜单不会关闭。 (所以如果用户点击第二个链接我想关闭下拉菜单) // main.js
我正在尝试制作一个导航下拉菜单(使用 Bootstrap 3),其中链接文本在同一行上有多个不同的对齐方式。 在下面的代码中,下拉列表 A 中的链接在 HTML 中有空格字符来对齐它们,但是空白被忽略
我希望有人能帮我解决这个 Bootstrap 问题,因为我很困惑。 有人要求我在底部垂直对齐图像和其中包含图像的链接。 我面临的问题是他们还希望链接在链接/图像组合上具有 pull-right,这会杀
我正在构建一个 Rails 应用程序,并希望指向我的类的每个实例的“显示”页面的链接显示在“索引”页面的下拉列表中。我目前正在使用带有 options_from_collection_for_sele
我有以下 Bootstrap3 导航菜单 ( fiddle here )。我想设置“突出显示”项及其子链接与下拉列表 1 和 2 链接不同的链接文本(和悬停)的样式。我还希望能够以不同于 Highli
我对导航栏中的下拉菜单有疑问。对于普通的导航链接(无下拉菜单),我将菜单文本放在 H3 中,但是当我尝试对下 zipper 接执行相同操作时,箭头不在标题旁边,而是在标题下方。我决定用 span 替换
我是一名优秀的程序员,十分优秀!