5

After sending some tcp data with the blocking/non-blocking methods such as:

Socket.Send() or Socket.SendAsync()

How can I know that my data has received an ACK message?

Can .NET know if TCP data has been successfully sent?

Justin Tanner
  • 13,409
  • 16
  • 75
  • 99
  • 1
    .NET Framework delegates such tasks to Windows Sockets API so you don't need to care about that. If anything serious happens, you will receive SocketException objects. Note that you misunderstood the documentation. SendAsync will return immediately after called. The data sending task is executing in background. That's the asynchronous pattern. – Lex Li Dec 07 '09 at 23:33
  • Corrected the question to avoid confusion. I'm trying to focus on how can you know when your data has been accepted by the other-side of the connection. – Justin Tanner Dec 08 '09 at 02:49

7 Answers7

14

The only way to know for sure is to implement some kind of application-level acknowledgement. The TCP level "ACK" packet is not exposed to the application level at all, so you have to use something more than that.

Greg Hewgill
  • 828,234
  • 170
  • 1,097
  • 1,237
  • 1
    Also the frequency of ACKs is nothing an application can control. Certain optimizations e.g. for high latency network links might change the behavior dramatically. http://blogs.technet.com/mrsnrub/archive/2009/05/26/on-bandwidth-and-latency.aspx – Alex Dec 07 '09 at 21:57
  • 1
    Like, for instance... SharpPcap or Pcap.Net? I'm not sure why this is the accepted answer as it doesn't answer the question being asked. – Evan Plaice Nov 10 '10 at 08:11
5

You make the other end respond to it.

Even if TCP has Acked it, if the receiving end terminates (for good or bad reasons) before processing the message and acting on it, you still don't know, so the only way to know is for the other end to tell you.

Simeon Pilgrim
  • 9,300
  • 26
  • 32
3

This information isn't available from .net's class libraries. I had the same kind of considerations when I started working on this port scanner in C#. I have made use of a .NET wrapper for libpcap (after installing the corresponding driver), the SharpPcap (http://sourceforge.net/projects/sharppcap/), in order to get this kind of information. The ACK packets are obtained through SharpPcap's interface (invoking the native libpcap interface's transparently).

My application is NScanner Port Scanner/Sweeper and you can find the code at codeplex, referencing to you my simple usage of the aforementioned library (http://nscanner.codeplex.com/).

I hope I helped.

Aggelos Biboudis
  • 1,167
  • 8
  • 27
  • +1 for Sharppcap. Create a sniffer with the filters 'tcp' and 'destination ip address' to match that of the host expecting the ack. Then parse the TCP headers and check the fields to match the ack replies that are expected. If you don't have a way to find the outgoing requests for ack just instantiate another sniffer with 'tcp' and 'source ip address' of the host sending the request for ack. – Evan Plaice Nov 10 '10 at 08:15
2

"I'm trying to focus on how can you know when your data has been accepted by the other-side of the connection."

I think you need to be aware what type of application layer protocol you are going to implement and what impact this has on application performance.

Take HTTP as an example of a "Streaming like" protocol. A server posts a stream of data to a client. There are no more additional application layer "ACKs" and the server doesn't actually care when and how exactly his stream of data arrives. This is very efficent on high latency links.

Now compare this to SMB! Instead of streaming a file, data is partitioned into blocks. Every successfully transferred block of data is acked on the application layer. This gives you more control, however, it effectively kills the protocol on WAN networks (check out "Bandwidth Delay Product").

Taking this into consideration, you can come up with your own design for your custom protocol.

Alex
  • 1,917
  • 1
  • 15
  • 31
1

I recommend using Pcap.Net.

You can easily sniff packets using this library in C# and then easily check the packet values.

You can also easily build and send packets.

brickner
  • 6,367
  • 1
  • 37
  • 52
0

If you are really certain that you need to know the packet level details of your TCP connection, then in addition to creating the TCP socket for sending, you need your application to use the winpcap API to look at the raw traffic as well. You can install a filter to only receive packets relevant to the particular IP,port combination that determines your remote side.

There are a couple of projects out there creating .NET wrappers for libpcap, for example here

bdk
  • 4,651
  • 25
  • 32
-1

The TCP layer will keep resending the packet until it receives a successful ACK.

Send will block until this happens - SendAsync will not block, and you can continue processing other stuff while the TCP layer handles sending the packet.

Anon.
  • 52,397
  • 8
  • 74
  • 83
  • This is good, but again, how do you know programmatically that your data has arrived correctly or failed? – Justin Tanner Dec 08 '09 at 02:46
  • 4
    Send only blocks till user buffer is copied to the kernel. From an application perspective, Send has nothing to do with actual message transmission and retries. – Jimm Dec 05 '12 at 18:56