UDP missing packets - c#

The problem: UDP packets are missing.
How could I capture every single UDP packet that is hitting the port?
I want to put received packet on the queue for preprocessing in the background and continue capturing new UDP packets without a single UDP packet loss?
public void Main()
{
Socket client = new(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
....
Console.WriteLine("Collecting data..");
while (true)
{
CaptureUDPPacket(client, _ep);
}
}
What is the best way to implement this feature?
Best regards!

Related

UDP NAT Hole Punching on separate UdpClient objects

I believe I am having an issue with NAT hole punching via UdpClient objects. I have a simple class that looks like:
class UdpConnection
{
UdpClient udpSend { get; set; }
UdpClient udpRecv { get; set; }
IpEndPoint TargetEndPoint { get; set; }
UdpConnection(IPEndPoint targetEndPoint)
{
TargetEndPoint = targetEndPoint;
}
void SendTo(byte[] bytes)
{
udpSend.Client.SendTo(bytes, TargetEndPoint);
}
void TryToConnect () { // ... // }
void WaitForConnect () { // ... // }
}
A client will use one of these objects and call TryToConnect(). The client will then use UdpConnection.udpRecv.Client.SendTo() to send a Hello packet to the server and then sleep for a second waiting for a response. When the Hello is acknowledge it then uses UdpConnection.udpRecv only for listening, updates the UdpConnection.udpSend object to use the target port given by the server to send further data and is then considered connected.
A server uses a dedicated UdpClient object to listen on for new connections. When it receives a new remote address it creates a new UdpConnection object with the new address, creates an Acknowledgement packet providing the specific port for this new connection to send data to and then listen on that port and send the Acknowledgement packet.
This all works when ran locally but the client will fail to receive the Acknowledgement packet when ran remotely. What makes me think this is a NAT Hole punching issues is that if I send the acknowledgement back on the server's listening port, the one that received the new connection, the client receives it. This makes me feel like I am missing something.
Where have I gone wrong? Is it that I am attempting to hand off the response to a new UdpClient instead of the one the client connected to? Do I have to handle the whole handshake on the Listening Port until the client uses its new dedicated port on the server?

C# TCP Socket Communicator - handle special messages between client and server

I want to learn about socket communication so I decided to try to write WP 8.1 text communicator. It is based on TCP sockets. I almost managed to finish it, but I am searching for improvemenets.
What is worth mentioning I use a socket server between phones (console application), to avoid problems with private ip addresses. It contains information about all connected users and forwards messages to clients (for instance user A sends message to user B, so firstly message goes to server and server forward it to destination address).
The problem appeared when i realized that I need to send special messages from server to client and vice versa (for example when two clients want to have conversation, they send request to server, so it knows where to forward messages).
This is my connection listener method from server application
private void ConnectionListener()
{
IPEndPoint localDataEndPoint = new IPEndPoint(IPAddress.Parse(LocalIpAddress), 1234);
IPEndPoint localMessageEndPoint = new IPEndPoint(IPAddress.Parse(LocalIpAddress), 4321);
Socket dataConnectionListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Socket messageConnectionListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
dataConnectionListener.Bind(localDataEndPoint);
dataConnectionListener.Listen(100);
messageConnectionListener.Bind(localMessageEndPoint);
messageConnectionListener.Listen(100);
while (true)
{
TcpSocket.clientDone.Reset();
IAsyncResult tmp1 = dataConnectionListener.BeginAccept(ConnectionCallback, null);
IAsyncResult tmp2 = messageConnectionListener.BeginAccept(ConnectionCallback, null);
TcpSocket.clientDone.WaitOne();
Socket dataSocket = dataConnectionListener.EndAccept(tmp1);
Socket messageSocket = messageConnectionListener.EndAccept(tmp2);
TcpSocket tmpTcpSocket = new TcpSocket(dataSocket, messageSocket);
tmpTcpSocket.Start();
connectedUsersSockets.Add(tmpTcpSocket);
UpdateConnectedUserList();
}
}
catch (Exception ex)
{
Log.E("Connection listener ran into an exception", ex);
}
}
As you can see I have created two TCP sockets to liesten on different ports. dataSocket is for normal messages and messageSocket is for special messages (sorry for confusing names, I have to refractor code).
On client side it works the same way: there are two different socket to communicate with and through the server.
I wanted to avoid managing two sockets rather then one. But the only way I can imagine is that on every received message server would have to check if it's special (and handle it in special way) or just send to client.
The question: Is there a better way to manage these special messages?
Thanks to all in advance!
P.S.
Sorry for my poor english, it's not my native language

Does broadcasting over UDP repeatedly send its packet, or just once?

Using C#, does broadcasting over UDP repeatedly send its packet, or just once?
I've never used this technology before and I want to temporarily broadcast small bit of info (a small one line string) over the LAN. If the receiving end isn't ready will the broadcast repeat itself or was it a one time thing? The code I'm using is from here. So what I want to start the Broadcaster one one machine and a few minutes later start the receiver and retrieve what the broadcaster sent.
Here is the code
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class Broadcst
{
public static void Main()
{
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram,
ProtocolType.Udp);
IPEndPoint iep1 = new IPEndPoint(IPAddress.Broadcast, 9050);
IPEndPoint iep2 = new IPEndPoint(IPAddress.Parse("192.168.1.255"), 9050);
string hostname = Dns.GetHostName();
byte[] data = Encoding.ASCII.GetBytes(hostname);
sock.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.Broadcast, 1);
sock.SendTo(data, iep1);
sock.SendTo(data, iep2);
sock.Close();
}
}
UDP by design only sends a packet once. It has no concept of handshakes (unlike TCP), error correction, or transmission guarantees. You can't even be sure that your data gets to where you send it unless you manually request checksums or something like that.
Wikipedia has a nice section on this: Reliability and congestion control solutions in UDP.
So, yes, you will need to implement transmission guarantee code if you want reliability. But what if the message from the recipient saying that the data was received is delayed? Well, then you need to implement some kind of timeout. What if the message gets lost? You need to resend the data to the recipient. How do you know if the recipient gets it this time? Etc...
If you don't want to do this, then I'd suggest looking into TCP which automatically manages this for you.

Flowcode Transmits UDP but Unsuccssefully read by the server

I'm using Flowcode technology to program a micro controller 16F877A.
from flowcode i'm sending 3 bytes UDP packets to a server listening on port 23456.
the problem is that the server never receives those packets. i used wireshark for tracing and it was able to detect the 3 bytes and its content.
below is my server code using c#
const int port_number=23456;
TcpListener server=new TcpListener( IPAddress.Any ,port_number);
Socket soc;
NetworkStream s;
bool exit=false;
Thread mythread;
thread code is here
void method()
{
try
{
server.Start();
soc = server.AcceptSocket();
s = new NetworkStream(soc);
StreamReader sr = new StreamReader(s);
textBox1.Text += sr.ReadLine();
if(soc.Connected==true && exit==false)
method();
}
catch(Exception es)
{
Console.WriteLine("{0}",es.Message);
}
}
do you think i need to change anything to be able to read those 3 bytes and process them.
i really appreciate your help.
You are using a TcpListening, but you are sending UDP packets? Try the UDPClient class: http://msdn.microsoft.com/en-us/library/system.net.sockets.udpclient.aspx
Edit
To elaborate a little bit. A TCP Client will never receive UDP packets, since TCP and UDP are two separate protocols at the socket level. The socket will see you are listening for a TCP connection, it will receive the UDP datagram, see no listeners, and throw it away.

Help me to choose Socket or TCPListener

I read 2 C# chat source code & I see a problem:
One source uses Socket class:
private void StartToListen(object sender , DoWorkEventArgs e)
{
this.listenerSocket = new Socket(AddressFamily.InterNetwork , SocketType.Stream , ProtocolType.Tcp);
this.listenerSocket.Bind(new IPEndPoint(this.serverIP , this.serverPort));
this.listenerSocket.Listen(200);
while ( true )
this.CreateNewClientManager(this.listenerSocket.Accept());
}
And other one uses TcpListener class:
server = new TcpListener(portNumber);
logger.Info("Server starts");
while (true)
{
server.Start();
if (server.Pending())
{
TcpClient connection = server.AcceptTcpClient();
logger.Info("Connection made");
BackForth BF = new BackForth(connection);
}
}
Please help me to choose the one. I should use Socket class or TcpListener class. Socket connection is TCP or UDP? Thanks.
UDP is connectionless, but can have a fake connection enforced at both ends on the socket objects. TCP is a stream protocol (what you send will be received in chunks on the other end), and additionally creates endpoint sockets for each accepted socket connection (the main listening socket is left untouched, although you'd probably need to call listen() again). UDP uses datagrams, chunks of data which are received whole on the other side (unless the size is bigger than the MTU, but that's a different story).
It looks to me like these two pieces of code are both using TCP, and so as the underlying protocol is the same, they should be completely compatible with each other. It looks as if you should use the second bit of code since it's higher level, but only the server can really use this, the client needs a different bit of code since it doesn't listen, it connects... If you can find the 'connecting' code at the same level of abstraction, use that.

Categories

Resources