[英]recvfrom only receive few packets after that it goes in waiting state
Hi I am new in Socket Programming and try to create a client server applciation using in which my server is Camera and client in my C++ application. 嗨,我是Socket编程的新手,并尝试使用C ++应用程序中的服务器和Camera来创建客户端服务器应用程序。 When I see the packet transfer between computer and camera it showing that camera is sending more than 150000 packets after that it stops.
当我看到计算机与相机之间的数据包传输时,表明相机在停止后发送了150000个以上的数据包。 But when I am receving that I am able to receive
400 - 450 packets
at a time after that the recvfrom
function goes to waiting state. 但是,当我接收到
recvfrom
函数进入等待状态后,我能够一次接收400-450 400 - 450 packets
。 and If I again run that exe file without stopping the previous one it again receive 400-450 packets
. 如果我在不停止前一个exe文件的情况下再次运行它,它将再次接收
400-450 packets
。
Code for Receving Packets 接收数据包的代码
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;
}
}
I am running the .exe with the administrator rights. 我正在以管理员权限运行.exe。
So can anyone please tell me why the recvfrom function is going in waiting state. 所以任何人都可以告诉我为什么recvfrom函数进入等待状态。
Thanks in Advance. 提前致谢。
EDIT:- 编辑:-
Sorry that I am providing the whole code. 抱歉,我提供了完整的代码。
#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
}
In the above code I have to first send this 59 commands
written in _packetConfig
function then only camera will send Image packets
I am receiving the reply of all that commands. 在上面的代码中,我必须首先发送用
_packetConfig
函数编写的这59 commands
,然后只有摄像机会发送Image packets
我正在接收所有这些命令的答复。
When I run wireshark also with that code I can see that after these 59 commands the camera is giving 3580*51
packets.ie 51 frames and each frame contain 3580 packets 当我也使用该代码运行wireshark时,我可以看到,在这59条命令之后,相机给出了
3580*51
包,即51帧,每帧包含3580包
Thank you for posting your code. 感谢您发布代码。 There are actually a few things wrong with it so first I will post some code that works as a reference and then mention the major issues I noticed with yours afterwards.
实际上存在一些问题,因此首先我将发布一些代码作为参考,然后再提及我在您的代码中发现的主要问题。
OK, here is some code that works for me: 好的,这是一些对我有用的代码:
#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;
}
To run this in 'send' mode, specify send as the first argument on the command line. 要在“发送”模式下运行此命令,请在命令行上将send指定为第一个参数。 Otherwise it acts as a receiver (aka server).
否则,它将充当接收器(也称为服务器)。
So what's wrong with your code? 那么您的代码有什么问题呢? Well, in no particular order:
好吧,没有特定的顺序:
SOCK_RAW
SOCK_RAW
bind
on the receiving socket so that it knows what port to listen on. bind
,以便它知道要侦听的端口。 The sockaddr *from
parameter to recvfrom
doesn't mean what you think it means (please check the docs ). sockaddr *from
参数到recvfrom
并不意味着您认为它意味着什么(请检查docs )。 You will see I pass this as NULL. WSAStartup
. WSAStartup
的返回值。 Again, please check the docs. But having said all that, it was essentially the call to bind
that you were missing. 说了这么多,本质上就是您缺少
bind
的呼吁。 I rewrote the code because yours is rather messy. 我重写了代码,因为您的代码很乱。
Also, important detail, UDP doesn't guarantee delivery - there are a number of reasons why a packet that has been sent does not get received or might even get received out of sequence (does your camera sequence the packets in some way?) 另外,重要的细节是,UDP无法保证传递-有许多原因导致已发送的数据包没有被接收,甚至可能被乱序接收(您的相机是否以某种方式对数据包进行了排序?)
You need to cater for that in the logic of your application (and it that's a problem, it's better to use TCP, which does guarantee packet delivery and sequencing). 您需要在应用程序的逻辑中满足这一要求(这是一个问题,最好使用TCP,它可以保证数据包的传递和排序)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.