- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
您好,我是 Socket 编程的新手,我尝试创建一个客户端服务器应用程序,其中我的服务器是相机,我的 C++ 应用程序中是客户端。当我看到计算机和相机之间的数据包传输时,它显示相机在停止后发送了超过 150000 个数据包。但是,当我收到我能够一次接收 400 - 450 个数据包
时,recvfrom
函数进入等待状态。如果我在不停止前一个文件的情况下再次运行该 exe 文件,它将再次收到 400-450 个数据包
。
接收数据包代码
SOCKET out1 = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
if (out1 == INVALID_SOCKET)
{
cout << out1 << endl;
}
server.sin_family = AF_INET;
server.sin_port = htons(3956);
inet_pton(AF_INET, "192.168.1.140", &server.sin_addr);
int serverLength = sizeof(server);
connect(out1, (sockaddr*)&server, serverLength);
while (1)
{
memset(buf, 0, sizeof(buf));
int bytesIn = recvfrom(out1, buf, 1444, 0, (sockaddr*)&server, &serverLength);
if (bytesIn > 0)
{
cout << "Image Received :" << bytesIn <<packet_counter << endl;
packet_counter++;
}
else
{
cout << "Not Received : " << endl;
}
}
我正在使用管理员权限运行 .exe。
谁能告诉我为什么 recvfrom 函数会进入等待状态。
提前致谢。
编辑:-
抱歉,我提供了完整的代码。
#include <stdio.h>
#include <Windows.h>
#include <thread>
#include <WinSock2.h>
// Library
#pragma comment(lib, "ws2_32.lib")
using namespace std;
//***** Function Decleration *****//
void _packetConfig(SOCKET);
void _sendPacket(SOCKET, const char*, int, int);
// Global Variable
sockaddr_in server;
//***** Main Function *****//
void main(char argc, char* argv[])
{
WSADATA data;
WORD version = MAKEWORD(2, 2);
if(WSAStartup(version, &data) == SOCKET_ERROR)
{
cout << "Can't Start Socket" << WSAGetLastError<<endl;
return;
}
char buf[2000];
SOCKET out1 = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
if (out1 == INVALID_SOCKET)
{
cout << out1 << endl;
}
server.sin_family = AF_INET;
server.sin_port = htons(3956);
inet_pton(AF_INET, "192.168.1.140", &server.sin_addr);
int serverLength = sizeof(server);
connect(out1, (sockaddr*)&server, serverLength);
int packet_counter = 0;
SOCKET out = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
_packetConfig(out);
cout << "Inside Main" << endl;
while (1)
{
//connect(out1, (sockaddr*)&server, serverLength);
memset(buf, 0, sizeof(buf));
int bytesIn = recvfrom(out1, buf, 1444, 0, (sockaddr*)&server, &serverLength);
if (bytesIn > 0)
{
cout << "Image Received :" << bytesIn <<packet_counter << endl;
packet_counter++;
}
else
{
cout << "Not Received : " << endl;
}
}
WSACleanup();
}
//***** Function to Send Bytes to the Camera *****//
void _sendPacket(SOCKET sock, const char* s, int len, int i)
{
int sendOk = sendto(sock, (const char*)s, len, 0, (sockaddr*)&server, sizeof(server));
if (sendOk == SOCKET_ERROR)
{
cout << "Didn't Work" << WSAGetLastError() << endl;
}
else
{
cout << "\nSend Succesfully" << " " << i << endl;
}
char buf[2000];
int serverLength = sizeof(server);
int bytesIn = recvfrom(sock, buf, 2000, 0, (sockaddr*)&server, &serverLength);
if (bytesIn > 0)
{
cout << "Message Received :" << bytesIn << endl;
}
}
//***** Function to call the _sendPacket function and send commands to the Camera *****//
void _packetConfig(SOCKET sock)
{
// 59 Commands and every command call _snedPacket function to send commands to camera it will working properly
}
在上面的代码中,我必须首先发送这个用_packetConfig
函数编写的59命令
,然后只有相机会发送我收到的图像数据包
所有命令的回复。
当我也使用该代码运行 wireshark 时,我可以看到在这 59 个命令之后相机给出 3580*51
数据包。即 51 帧,每帧包含 3580 个数据包
最佳答案
感谢您发布代码。它实际上有一些问题,所以首先我将发布一些代码作为引用,然后提及我在之后注意到的主要问题。
好的,这是一些适合我的代码:
#include <WinSock2.h> // ** before** windows.h
#include <WS2tcpip.h>
#include <iostream>
#include <stdio.h>
#include <Windows.h>
#include <assert.h>
#pragma comment (lib, "ws2_32.lib")
const int port = 3956;
// main
int main (char argc, char* argv[])
{
WSADATA wsadata;
WORD version = MAKEWORD(2, 2);
int err = WSAStartup (MAKEWORD (2, 2), &wsadata);
if (err)
{
std::cout << "WSAStartup failed, error: " << err << std::endl;
return 255;
}
char buf [1444];
bool send = argc > 1 && _stricmp (argv [1], "send") == 0;
if (send)
{
// Send
SOCKET skt_out = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
assert (skt_out != INVALID_SOCKET);
sockaddr_in destination_address = { };
destination_address.sin_family = AF_INET;
destination_address.sin_port = htons (port);
inet_pton (AF_INET, "192.168.1.2", &destination_address.sin_addr);
memset (buf, 'Q', sizeof (buf));
printf ("Sending: ");
for ( ; ; )
{
sendto (skt_out, buf, sizeof (buf), 0, (const sockaddr *) &destination_address, sizeof (destination_address));
printf (".");
Sleep (50);
}
closesocket (skt_out);
WSACleanup ();
return 0;
}
// Receive
SOCKET skt_in = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
assert (skt_in != INVALID_SOCKET);
int receive_buffer_size = 65536;
if ((setsockopt (skt_in, SOL_SOCKET, SO_RCVBUF, (const char *) &receive_buffer_size, sizeof (int)) ) < 0)
std::cout << "Could not set SO_RCVBUF, error: " << WSAGetLastError () << std::endl;
sockaddr_in receive_address = { };
receive_address.sin_family = AF_INET;
receive_address.sin_port = htons (port);
receive_address.sin_addr.s_addr = htonl (INADDR_ANY);
if (bind (skt_in, (const sockaddr *) &receive_address, sizeof (receive_address)) == -1)
{
std::cout << "bind failed , error: " << WSAGetLastError () << std::endl;
return 255;
}
int packetCounter = 0;
printf ("Receiving: ");
for ( ; ; )
{
int bytesIn = recvfrom (skt_in, buf, sizeof (buf), 0, NULL, 0);
if (bytesIn > 0)
std::cout << "Packet received:" << bytesIn << " bytes (" << ++packetCounter << ")" << std::endl;
else
std::cout << "Receive error: " << WSAGetLastError () << std::endl;
}
closesocket (skt_in);
WSACleanup ();
return 0;
}
要在“发送”模式下运行它,请将send 指定为命令行中的第一个参数。否则它充当接收器(也称为服务器)。
那么你的代码有什么问题?好吧,排名不分先后:
SOCK_RAW
bind
以便它知道要监听哪个端口。 sockaddr *from
参数到 recvfrom
并不意味着你认为它意味着什么(请检查 docs )。您会看到我将其作为 NULL 传递。WSAStartup
的返回值。同样,请检查文档。但是说了这么多,您实际上缺少对 bind
的调用。我重写了代码,因为你的代码比较乱。
另外,重要的细节,UDP 不保证传送 - 有很多原因导致已发送的数据包未收到或什至可能收到乱序(您的相机是否以某种方式对数据包进行排序?)
您需要在应用程序的逻辑中满足这一点(这是一个问题,最好使用 TCP,它可以保证数据包的传送和排序)。
关于c++ - recvfrom 在进入等待状态后只收到很少的数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51028499/
我有 python 应用程序,它需要每天执行大约 20 000 次专有应用程序(不时崩溃)。 问题是当应用程序崩溃时,Windows 会自动触发 WerFault这将使程序挂起,因此 python's
我弄清楚这里的问题是什么。很少(50 个数据中有 3 个)插入到数据库中的数据不完整,如下所示: 用于插入的 PHP 代码是正确的。数据库中没有值的所有值都来自 SELECT 标记 HTML(year
我有一个包含对象的列表,其中包含以下字段:完整、不完整、继续。我想根据这三个部分对我的列表进行排序。首先,我想添加 header: INCOMPLETE 和所有元素(如果此字段为真)。之后我想添加标题
我们有一个名为模型的包 在模型中,我们有一个 TopicM 模块,它定义了一个类 Topic我们将它导入同一个包中名为 GeneralM 的模块中。有时(很少)我们会收到此错误: 可能是什么原因?会不
通过简单地将 TextViews 文本设置为在代码中定义的字符串(永远不能是 null)我有时会得到一个 ArrayIndexOutOfBoundsException,这只发生在我的实时应用程序中,我
我在 NodeJS 中运行一个 restify 服务器。在极少数情况下,大约 0.05% 的 HTTPS 请求会导致 net.js 报告以下错误: Error: accept EPERM at
我不明白,为什么Eclipse更新变得如此不可靠?大约每次使用它时,我都会遇到一些问题! 例如,现在我遇到下面一堆谵妄。禁用“联系所有软件站点”没有帮助。 An error occurred whil
为了呈现一堆节点,每帧一个,直到它们都出现在屏幕上,我想在 update() 调用中做这样的事情。 警告,伪代码接近: update(){ switch presentNodes_inOrderOfA
此 NSPersistentStoreCoordinator 没有持久存储。它无法执行保存操作。 NSInternalInconsistencyException(SIGABRT) This NSPe
我是一名优秀的程序员,十分优秀!