Regarding implementing a new transport protocol [closed] - c

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.

Related

Sending multiple strings over tcp soket in C loses data [duplicate]

This question already has answers here:
Is there complete isolation between two sendalls in the same TCP connection?
(1 answer)
Can't receive multiple messages on server using TCP socket (Python)
(1 answer)
Python TCP Server receives single TCP packet split into multiple packets
(2 answers)
Closed 8 months ago.
I'm working on a C project that implements a TCP client-server. The sockets and the send() functions i'm using are the one defined in the libraries sys/socket.h and winsock2.h.
My problem is that when i try to send multiple strings one after the other, some messages aren't transmitted correctly, with some data (sometimes all the message) that goes missing. The following code, for example, works without a problem when i'm running server and client on the same machine, but if I try to run it with a remote server, then the third message isn't properly received.
Client Side
char message[1024];
memset(message, 0, 1024);
fill_message(message, msg1); //A function that prints something in the message string.
//It may fill less than 1024 characters.
send(clientSocket, message, 1024,0);
fill_message(message, msg2);
send(clientSocket, message, 1024,0);
fill_message(message, msg3);
send(clientSocket, message, 1024,0);
Server Side
char message[1024];
memset(message, 0, 1024);
recv(clientSocket, message, 1024,0);
print_and_do_stuff(message);
recv(clientSocket, message, 1024,0);
print_and_do_stuff(message);
recv(clientSocket, message, 1024,0);
print_and_do_stuff(message);
Note: the string message may not be exactly of length 1024.
My solution has been to make the client wait for 1 second by calling sleep(1) after each message is sent. Is this the proper way to address the issue? Or am i missing something about how send() and recv() work?
More in general: what is the "proper" way to program with sockets? Should I maybe be sending the message byte-by-byte and specifying the length as the first thing? If someone could point me toward a good tutorial/guide on what the best practices are when working with sockets, I'd be happy to read it.
Socket functions may or may not read/send the entire data in one call, which means that you have to verify the correct reception server side, and maybe create a custom protocol on top of TCP to keep track of the size you sent and received.
TCP, contrary to UDP, guarantees the integrity of data, meaning that you won't lose anything when sending, but you may need to use multiple function calls to ensure all of the data has been sent and red.
As for good tutorial and guides, as someone already said in comments, you can find loads of examples and guides about it.

TCP: Socket send/recv order [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 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.

TCP Sockets in C with bad network

I am doing some test with TCP client application in a Raspberry Pi (server in the PC), with PPP (Point to Point Protocol) using a LTE Modem. I have used C program with sockets, checking system call's response. I wanted to test how socket works in a bad coverage area so I did some test removing the antenna.
I have followed the next steps:
Connect to server --> OK
Start sending data (write system call) --> OK (I also check in the server)
I removed the LTE modem's antenna (There is no network, it can't do ping)
Continue sending data (write system call) --> OK (server does not receive anything!!!)
It finished sending data and closed socket --> OK (connection is still opened and there is no data since the antenna was removed)
Program was finished
I put the antenna again
Some time later, the data has been uploaded and the connection closed. But I did another test following this steps but with more data, and it did not upload this data...
I do not know if there any way to ensure that the data written to TCP server is received by the server (I thought that TCP layer ensured this..). I could do it manually using an ACK but I guess that it has to be a better way to do.
Sending part code:
while(i<100)
{
sprintf(buf, "Message %d\n", i);
Return = write(Sock_Fd, buf, strlen(buf));
if(Return!=strlen(buf))
{
printf("Error sending data to TCP server. \n");
printf("Error str: %s \n", strerror(errno));
}
else
{
printf("write successful %d\n", i);
i++;
}
sleep(2);
}
Many thanks for your help.
The write()-syscall returns true, since the kernel buffers the data and puts it in the out-queue of the socket. It is removed from this queue when the data was sent and acked from the peer. When the OutQueue is full, the write-syscall will block.
To determine, if data has not been acked by the peer, you have to look at the size of the outqueue. With linux, you can use an ioctl() for this:
ioctl(fd, SIOCOUTQ, &outqlen);
However, it would be more clean and portable to use an inband method for determining if the data has been received.
TCP/IP is rather primitive technology. Internet may sound newish, but this is really antique stuff. TCP is needed because IP gives almost no guarantees, but TCP doesn't actually add that many guarantees. Its chief function is to turn a packet protocol into a stream protocol. That means TCP guarantees a byte order; no bytes will arrive out of order. Don't count on more than that.
You see that protocols on top of TCP add extra checks. E.g. HTTP has the famous HTTP error codes, precisely because it can't rely on the error state from TCP. You probably have to do the same - or you can consider implementing your service as a HTTP service. "RESTful" refers to an API design methodology which closely follows the HTTP philosophy; this might be relevant to you.
The short answer to your 4th and 5th topics was taken as a shortcut from this answer (read the whole answer to get more info)
A socket has a send buffer and if a call to the send() function succeeds, it does not mean that the requested data has actually really been sent out, it only means the data has been added to the send buffer. For UDP sockets, the data is usually sent pretty soon, if not immediately, but for TCP sockets, there can be a relatively long delay between adding data to the send buffer and having the TCP implementation really send that data. As a result, when you close a TCP socket, there may still be pending data in the send buffer, which has not been sent yet but your code considers it as sent, since the send() call succeeded. If the TCP implementation was closing the socket immediately on your request, all of this data would be lost and your code wouldn't even know about that. TCP is said to be a reliable protocol and losing data just like that is not very reliable. That's why a socket that still has data to send will go into a state called TIME_WAIT when you close it. In that state it will wait until all pending data has been successfully sent or until a timeout is hit, in which case the socket is closed forcefully.
The amount of time the kernel will wait before it closes the socket,
regardless if it still has pending send data or not, is called the
Linger Time.
BTW: that answer also refers to the docs where you can see more detailed info

Can LoadRunner Receive Data By UDP Packets?

We want to receive packets from udp sockets, the udp packets have variable length and we don't know how long they really are until we receive them (parts of them exactly, length were written in the sixth byte).
We tried the function lrs_set_receive_option with MarkerEnd only to find it has no help on this issue. The reason why we want to receive by packets is that we need to respond some packet by sending back user-defined udp packets.
Is there anybody knows how achieve that?
UPDATE
The LR version seems to be v10 or v11.
We need respond an incoming udp packet by sending back a udp packet immediately.
The udp packet may be like this
| orc code | packet length | Real DATA |
Issue is we can't let loadrunner return data for each packets, sometimes it returns many packets in a buffer, sometimes it waits until timeout though when there has been an incoming packet in the socket buffer. While in the c programming language world, when calling recvfrom(udp socket) we are returned only one udp packet per time (per call) which is want we really want.
If you need raw socket support to intercept at the packet level then you are likely going to have to jump to a DLL virtual user in Visual Studio with the raw socket support.
As to your question on UDP support: Yes, a Winsock user supports both core transport types, UDP and TCP. TCP being the more common variant as connection oriented. However, packet examination is at layer 3 of the OSI model for the carrier protocol IP. The ACK should come before you receive the dataflow for your use in the script. You are looking at assembled data flows in the data.ws when you jump to the TCP and UDP level.
Now, you are likely receiving a warning on receive buffer size mismatch which is taking you down this path with a mismatch to the recording size. There is an easy way to address this. If you take your send buffer and construct it using the lrs_set_send_buffer() function, then anything that returns will be taken as correct, ignoring the previously recorded buffer size and not having to wait for a match or timeout before continuing.

implementing ack over UDP?

We have a system (built in C) in place that performs communication over UDP. Recently we have found a necessity to guarantee delivery of packets. My question is: what would be the minimum additions to a UDP based system to ensure delivery using ack packets? Also, ideally without having to manipulate the packet headers. We have application level control over the packets including sequence numbers and ack/nack flags. I am wondering if this is a lost cause and anything we attempt to do will basically be a flawed and broken version of TCP. Basically, is there a minimalist improvement we can make to achieve guaranteed delivery (we do not need many features of TCP such as congestion control etc.). Thanks!
TCP intertwines 3 services that might be relevant (okay TCP does a lot more, but I'm only going to talk about 3.)
In-order delivery
Reliable delivery
Flow control
You just said that you don't need flow control, so I won't even address that (how you would advertise a window size, etc. well, except that you'll probably need a window. i'll get to it.)
You did say that you need reliable delivery. That isn't too hard - you use ACKs to show that the sender has received a packet. Basic reliable delivery looks like:
Sender sends the packet
Receiver receives packet, and then sends an ack
If the sender doesn't get an ack (by way of a timer), he resends the packet.
Those three steps don't address these issues:
What if the ACK gets lost?
What if packets arrive out of order?
So for your application, you said you only needed reliable delivery - but didn't say anything about needing them in order. This will affect the way you implement your protocol.
(example where in-order doesn't matter: you're copying employee records from one computer to another. doesn't matter if Alice's record is received before Bob's, as long as both get there.)
So going on the presumption that you only need reliable (since that's what you said in your post), you could achieve this several ways.
Your sender can keep track of unacknowledged packets. So if it sends # 3, 4, 5, and 6, and doesn't get an ACK for 3 and 4, then the sender knows that it needs to retransmit. (Though the sender doesn't know if packets 3 and 4 were lots, or if their ACKs were lost. Either way, we have to retransmit.)
But then your sender could do cumulative ACKs - so in the above example, it would only ack #6 if it had received 3, 4, and 5. This means that the receiver would drop packet 6 if it hadn't received the ones before. If your network is very reliable, then this might not be a bad option.
The protocols described above, however, do have a window - that is, how many packets does the sender send at once? Which means that you do need some sort of windowing, but not for the purpose of flow control. How'll you transmit window sizes?
You could do it without a window by either having the window size constant, or by doing something like stop-and-wait. The former might be a better option.
Anyway, I haven't directly answered your question, but I hope I've pointed out some of the things that are worth considering when architecting this. The task of having "reliable transfer" without parts of flow control (like windowing) and without any regard to in-order is hard! (Let me know if I should give more details about some of this stuff!)
Good luck!
Take a look at Chapter 8 and Chapter 20 of Steven's UNIX Network Programming, volume 1. He covers a number of different approaches. Section 20.5 "Adding Reliability to a UDP Application" is probably most interesting to you.
I have a question running here which is collecting answers to "What to you use when you need reliable UDP". The answers are possibly much more than you want or need but you might be able to take a look at some of the protocols that have been built on UDP and grab just the ACK part that you need.
From my work with the ENet protocol (a reliable UDP protocol), I expect that you need a sequence number in each UDP datagram, a way of sending an ACK for datagrams that you've received, a way of keeping hold of datagrams that you've sent until you get an ACK for them or they time out and a way of timing the resending of datagrams for which you have yet to receive an ACK... I would also add an overall timeout for when you decide that you are never going to deliver a particular datagram, and, I guess, a callback to your application layer to inform it of this failure to deliver...
The best way to implement ack is to do it in the application layer. CoAP is an example of an application protocol which runs on udp but provides reliable data transfer. It keeps a message id for all the Confirmable(CON) messages and sends an receiver sends an ack packet with the same message id. All the ack and message id fields are kept at the application layer part. So if the sender doesn't receive an Ack packet with the message id send by him, it re transmits that packet. Application developer can modify the protocol to suit the needs required for reliable data transfer .
Tough problem. I would say, you wont be able to achieve the reliability of TCP. However, i do understand that sometimes, you need to have reliable UDP.
Gamedev forum
RUDP (a bit more hardcore)
Old Thread about reliable UDP

Resources