Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I have a udp client (I have no control over the source code) that is constantly sending data frames, one frame per 500ms, and I have a udp server that checks the last frame every 5 seconds.
The problem is that this udp server doesn't read the last frame but only the next frame in the udp buffer from the operating system.
n = recvfrom(server_sockfd, buf, BUFSIZE, 0, (struct sockaddr *) &new_dax[eqpID].clientaddr,
&new_dax[eqpID].clientlen);
With this code if my udpclient is sending :
FRAME 1 ->500ms
FRAME 2->500ms
FRAME 3->500ms
FRAME X->500ms
My udp server receives firstly FRAME 1, and then after 5 seconds when I try to read the frame from the client the server receveives FRAME 2 instead of FRAME X.
How do I get the last frame received? I tried closing the server socket and opening it again when I want to receive the last frame but this is consuming to much resources. Is it possible without closing the server socket?
Thanks!
You can use recvmmsg() to receive a whole bunch of messages at once. So in your case, you expect to receive about 10 messages per read, so set up buffers for 12-15 messages and just call recvmmsg() once, then ignore all but the last message.
You'll want to use the MSG_WAITFORONE flag, so that recvmmsg() doesn't block until all 12-15 messages are received--you only expect to receive 9-11 or so.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I am wondering if you need to set up the server and client sockets so that they always go
send recv send recv ...
Because I am getting an issue where I send a message, and then the initial send() receives it twice.
I send the message upload foo.c
Server displays: Message received: upload foo.c
But then the server prints the actual file contents, which should have been passed to another recv() socket call (since only the first socket in the while loop has it's contents printed)
Message received: This is some text from
the file foo.c
text hello ending
So I get the feeling it's "overflowing" into the next recv iteration.
I'm guessing you use TCP? Then you have to remember that TCP is a streaming protocol, without message boundaries and without any start or end (except connection established and closed).
A single recv call may receive less or more than what was sent in a single send call.
You need to come up with a higher-level protocol which incorporates message boundaries explicitly, for example by sending the length of the data to be received. Then you have to use loops to receive the correct amount of bytes.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I am trying to implement my own Transport Layer Protocol like TCP which will be used by some application, on top of network layer using raw sockets API in Linux. I am working on Ubuntu 14.04.
I have been able to send and receive packets.
Now in the part of implementing the Transport Protocol, I am looking forward to write some functions like
connect(int sockfd) - To establish connection to the server.
send_data(int sockfd, char* data) - To send data
receive_data(int sockfd, char* data) - To receive data
close(int sockfd) - close the connection
Also since I am trying to implement protocol like TCP, to keep the protocol reliable I want to send acknowledgement for each received data packet. I have made my own TCP like header as follows
typedef struct rtlp_hdr
{
int checksum;
short int src_port; //defined by us
short int des_port; //defined by us
int seq_no;
int ack_no;
}rtlp_hdr;
Now in the implementation of the send_data function after I send a data packet I wait to receive the acknowledgement for the next data packet for given time, and if I don't receive any ack or I receive a corrupted ack( after checking the checksum) I resend the data. I am facing problems in creating the corresponding receive_data function for the same, like how would I know that the ack sent for the received data has been successfully delivered to the sender, since there is no ack for ack.
If anyone has any ideas what can I do or if I am going in the wrong direction please correct me. thanks in advance.
I have already written code for the connect(int sockfd) using 3-way handshaking that is working fine, I can share that.
As mentioned, there is no way to guarantee that a message arrives at the destination. If i understand your question right i hope the simple example below can help you.
You have a client A, and a server B. Client A sends a packet named A1 to B.
B saves the name of the last received packet, and replies to A with an ack.
If the ack makes it to the client it sends the next packet, named A2.
If, however, the ack is lost, the client resends the data named A1 after a while.
When the server receives A1 a second time (using the saved name), it can assume that the ack was lost.
The server then resends the ack, hoping that it will make it to the client this time. This continues as many times as neccessary.
As you see, the server does not need to know if the ack has been delivered to the client. The receiving of a duplicate packet tells the server that the ack was lost. (ignoring spurious timeouts for simplicity)
You are facing the Byzantine Generals' problem of protocols: there is never a guarantee that a message arrives. If you send a message to ack that the message arrived, it may not arrive; if you send a poll to enquire if the message has arrived, it may never arrive or its answer may never arrive...
So protocols can at best be "mostly reliable" and in your design you must include non-arrival, and your software must be able to cope with it. "The software" may mean all the way up to the application layer.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I want to connect to a server, and synchronously write(2) to it.
At some point, buffers are filling up and I need to read(2) to let me continue writing.
read(2) is of course copying lots of bytes unnecessarily, and it's blocking if I don't know how many bytes to expect.
How can I discard incoming bytes on a TCP socket?
I've tried ioctl(sockfd, I_SRDOPT, RMSGD) but it's returning errno EFAULT Bad address.
You could use the socket in the non-blocking mode to periodically consume incoming data without blocking. To quote a tutorial:
If you call recv() in non-blocking mode, it will return any data that the system has in it's read buffer for that socket. But, it won't wait for that data. If the read buffer is empty, the system will return from recv() immediately saying "Operation Would Block!".
I have few doubts regarding frame boundaries in RTP packets.
First, If the marker bit is set, does it say that a new frame has begun(this is what I understand from RFC 3551)?
Second, According to what I read a frame starts with I-frame followed by P, B frames. Now, which field indicates this? And is the I frame has the marker bit set?
Third, If I need to find the start and end of a frame, would the check for marker bit suffice?
Thanks!
The RTP entry on the Wireshark Wiki provides a lot of information, including (edit) sample captures. You could exlore it, and it might answer some of your questions. If you're going to write code to work with RTP, Wireshark is useful for monitoring/debugging.
Edit For your first question about Marker bit, this FAQ might help. Also, finding the frames (I, P, B) depends on the payload. There's another question here that has an answer showing how I, P, B are found for MPEG. The h263-over-rtp.pcap has examples with I and P frames for H.263.
This in an old question but I think it is a good one.
As you mention I,P and B frames, in 2012 you are likely referring to H.264 over RTP.
According to [rfc6184]1 , the marker bit is set on the last packet of a frame , so indeed the marker bit can be used as an indicator of the end of 1 frame and the next packet in sequence will be the start of the next frame.
According to this rfc, all packets of a frame also have the same RTPTIME so changes in RTPTIME is another indicator of the ending of the previous frame and start of a new frame.
Things get more tricky when you lose packets. For example, let's say you lose packets 5 and 6 and that these were the last packet of frame 1 and the first packet of frame 2. You know to discard frame 1 because you never got a packet with a marker bit for that frame, but how can you know if frame 2 is whole or not. Maybe the 2 lost packets were both part of frame 1 or maybe the second packet was part of frame 2?
rfc6184 defines the start bit that is present in the first packet of a fragmented NAL unit. If the NAL unit is not fragmented then by definition, we got the whole NAL unit if we got the packet. This means that we can know if we got a full NAL unit. Unfortunately, this does not guarantee we have the full frame since a frame could contain multiple NAL units (e.g. multiple slices) and we may have lost the first one. I don't have a solution for this problem but maybe somone will provide one sometime in the next 10 years.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
Im playing with 'recvfrom' and 'sendto' calls using UDP.
I have a client that just broadcast UDP packets on port 6000.
I have a server that binds a socket on port 6000, and do a single recvfrom.
The problem is that sin_port member of struct sockaddr returned from recvfrom is always incorrect. Why?
I would post some source code but someone already posted that question (with no answers) and I'm using almost the same code as he. Besides, you can get further information about this problem reading his post: FORUM POST.
Thanks in advance
EDIT: I really think 'cause number 2' from 'nos' answer might be the problem. How can I check it?
Here's 2 likely causes:
You're not converting the sin_port to host order before you inspect/display it. sin_port comes in network endian. That is you might be displaying the port as big endian on a little endian machine.
Your client uses a random source port. So while your destination port is 6000, the source port of the client is randomly chosen. recvfrom gives you the source IP address and the source port no. Not the destination port.
If it's neither of these, please provide some relevant test code, and the actual values you are seeing. It's possible you e.g. have some buffer overflows, or something other fishy going on.
EDIT, looking at the code in your link, you hardcode the buffer size(udpPkg.udpRecvBuf) as 1024. Is the buffer really atleast 1024 big ? If not, you're probably overflowing udpPkg.udpRecvBuf.
Are you converting from network byte order?