TCP: Socket send/recv order [closed] - c

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.

Related

UDP: Read frame a NEW frame from client every x seconds [closed]

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.

client server using TCP in C [closed]

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 5 years ago.
Improve this question
I am working on client server project where I have to search data requested by client from a file that is on the server side.
My code on client side:
printf("Enter data to search: \n");
fgets(buf,sizeof(buf),stdin);
send(s,buf, strlen(buf),0);
printf("Result of your search: ");
if(len = recv(s, buf, sizeof(buf),0)>0)
printf("\nMessage Received From Server -\n %s\n",buf);
my code on server side:
fp=fopen("courses.txt","r");
len=recv(new_s,buf,sizeof(buf),0);
char temp[256],tmp[512];
char *search;
while(fgets(tmp, 512, fp)!=NULL)
{
search= strstr(tmp, buf);
if(search)
{
send(new_s,tmp,strlen(tmp),0);
}
}
The strstr() always returns a null value therefore it never enters the if statement.
TCP is not a message protocol. If you want to send and receive messages (which your query is) you need a message protocol. Start by defining precisely how messages are bounded (at the byte level) and then write code to send and receive a message.
Also, don't ignore the return value of recv. How do you know how many bytes you received? And don't use functions like strlen and strcpy for anything but a C-style string. For convenience, you can make your send and receive message functions take and return C-style strings. But don't assume data on the wire will be a C-style string until your code makes it one.

Regarding implementing a new transport protocol [closed]

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.

Ignoring incoming bytes on a Linux TCP socket [closed]

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!".

UDP recvfrom call returns wrong port number. Why? [closed]

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?

Resources