UDP client not receiving data - c#

I have a problem communicating with a UDP device
public IPEndPoint sendEndPoint;
public void senderUdpClient(byte message_Type, byte Command_Class, byte command_code,int argument1, int argument2)
{
string serverIP = "192.168.2.11";
int sendPort = 40960;
int receivePort = 40963;
// Calcul CheckSum
// We know the message plus the checksum has length 12
var packedMessage2 = new byte[12];
var packedMessage_hex = new byte[12];
// We use the new Span feature
var span = new Span<byte>(packedMessage2);
// We can directly set the single bytes
span[0] = message_Type;
span[1] = Command_Class;
span[2] = command_code;
// The pack is <, so little endian. Note the use of Slice: first the position (3 or 7), then the length of the data (4 for int)
BinaryPrimitives.WriteInt32LittleEndian(span.Slice(3, 4), argument1);
BinaryPrimitives.WriteInt32LittleEndian(span.Slice(7, 4), argument2);
// The checksum
// The sum is modulo 255, because it is a single byte.
// the unchecked is normally useless because it is standard in C#, but we write it to make it clear
var sum = unchecked((byte)packedMessage2.Take(11).Sum(x => x));
// We set the sum
span[11] = sum;
// Without checksum
Console.WriteLine(string.Concat(packedMessage2.Take(11).Select(x => $#"\x{x:x2}")));
// With checksum
Console.WriteLine(string.Concat(packedMessage2.Select(x => $#"\x{x:x2}")));
Console.WriteLine(string.Concat(packedMessage2.Take(1).Select(x => $#"\x{x:x2}")));
UdpClient senderClient = new UdpClient();
sendEndPoint = new IPEndPoint(IPAddress.Parse(serverIP), sendPort);
try
{
senderClient.Connect(this.sendEndPoint);
senderClient.Send(packedMessage2, packedMessage2.Length);
//IPEndPoint object will allow us to read datagrams sent from any source.
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Parse(serverIP), receivePort);
Thread.Sleep(5000);
// Blocks until a message returns on this socket from a remote host.
Byte[] receiveBytes = senderClient.Receive(ref RemoteIpEndPoint);
string returnData = Encoding.ASCII.GetString(receiveBytes);
senderClient.Close();
MessageBox.Show("Message Sent");
}
catch (Exception err)
{
MessageBox.Show(err.ToString());
}
}
Form1
ObjHundler.senderUdpClient(1, 1, 0x24, 0 , 0);
there I build my message and I send it via port 40960
and I got a response via port 40963
Wireshark
On wireshark I send the message and the equipment sends a response but the code crashes in this line
Byte[] receiveBytes = senderClient.Receive(ref RemoteIpEndPoint);
Without filling in the table and without displaying any error message
Is there something missing from my code?
what could be the problem
Netstat -a cmd pour l'ip que j'utilise pour l'envoie 192.168.2.20
[CMD Netstat -a]

The solution =
you must create a UDPClient for reading.
It worked for me
public void senderUdpClient()
{
string serverIP = "192.168.2.11";
int sendPort = 40960;
int receivePort = 40963;
UdpClient senderClient = new UdpClient();
sendEndPoint = new IPEndPoint(IPAddress.Parse(serverIP), sendPort);
try
{
senderClient.Connect(this.sendEndPoint);
senderClient.Send(packedMessage2, packedMessage2.Length);
//Creates a UdpClient for reading incoming data.
UdpClient receivingUdpClient = new UdpClient(receivePort);
//Creates an IPEndPoint to record the IP Address and port number of the sender.
// The IPEndPoint will allow you to read datagrams sent from any source.
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
try
{
// Blocks until a message returns on this socket from a remote host.
Byte[] receiveBytes = receivingUdpClient.Receive(ref RemoteIpEndPoint);
string returnData = Encoding.ASCII.GetString(receiveBytes);
Console.WriteLine("This is the message you received " +
returnData.ToString());
Console.WriteLine("This message was sent from " +
RemoteIpEndPoint.Address.ToString() +
" on their port number " +
RemoteIpEndPoint.Port.ToString());
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
//string returnData = Encoding.ASCII.GetString(receiveBytes);
senderClient.Close();
MessageBox.Show("Message Sent");
}
catch (Exception err)
{
MessageBox.Show(err.ToString());
}
}

Related

Cannot connect to another computer over TCP

I am working on a project that transfers files over TCP. It is written in .NET 4.7. The program works while the client connects on the server that is on the same computer but when I send it to a friend and I try to connect it I get an error:
A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
Currently the program only sends some information about the file that will be copied and is nothing is encrypted as I cannot send even these information.
Here's the code for the server (Invoke is used because it is run on a separate thread):
private void Server_Start()
{
try
{
// Set port on 13000
int port = 13000;
//Get the ip adress for the server
String localIp;
using (var client = new WebClient())
{
// Try connecting to Google public DNS and get the local endpoint as IP
// If failed to connect set IP as local IP
if (CheckForInternetConnection())
{
try
{
using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, 0))
{
socket.Connect("8.8.8.8", 65530);
IPEndPoint endPoint = socket.LocalEndPoint as IPEndPoint;
localIp = endPoint.Address.ToString();
}
}
catch (Exception e)
{
localIp = "127.0.0.1";
}
}
else
{
localIp = "127.0.0.1";
}
}
IPAddress IP = IPAddress.Parse(localIp);
// Create listener and start listening
server = new TcpListener(IP, port);
server.Start();
// Buffer for data
Byte[] bytes = new byte[256];
String data = string.Empty;
this.Invoke((MethodInvoker)(() => Log.Items.Add("Server started on ip: " + IP.ToString())));
while (true)
{
// Accepting requests
TcpClient client = server.AcceptTcpClient();
// Get the stream object
NetworkStream stream = client.GetStream();
// Read length of file name
byte[] nameLength = new byte[4];
stream.Read(nameLength, 0, 4);
int nameSize = BitConverter.ToInt32(nameLength, 0);
// Read the name of file
byte[] name = new byte[nameSize];
stream.Read(name, 0, nameSize);
String fileName = Encoding.UTF8.GetString(name);
// Read size of file
byte[] fileSizeB = new byte[4];
stream.Read(fileSizeB, 0, 4);
int fileSize = BitConverter.ToInt32(fileSizeB, 0);
// Read start signal
byte[] startB = new byte[9+1];
stream.Read(startB, 0, 9);
String start = Encoding.UTF8.GetString(startB);
this.Invoke((MethodInvoker)(() => Log.Items.Add("Size of name: " + nameSize.ToString())));
this.Invoke((MethodInvoker)(() => Log.Items.Add("Name of file: " + fileName)));
this.Invoke((MethodInvoker)(() => Log.Items.Add("File size: " + fileSize.ToString())));
this.Invoke((MethodInvoker)(() => Log.Items.Add("Start signal: " + start)));
// Response to client
byte[] message = Encoding.UTF8.GetBytes("Testmessage");
stream.Write(message, 0, message.Length);
}
server.Stop();
Log.Items.Add("Server started on ip: " + IP.ToString());
}
catch (Exception e)
{
this.Invoke((MethodInvoker)(() => Log.Items.Add(e)));
}
}
And here is the code for the client:
private void button1_Click(object sender, EventArgs e)
{
IPAddress iP = IPAddress.Parse(ConnectIp.Text);
int port = 13000;
int buffersize = 1024;
TcpClient client = new TcpClient();
NetworkStream netStream;
// Try to connect to server
try
{
client.Connect(new IPEndPoint(iP, port));
}
catch(Exception ex)
{
this.Invoke((MethodInvoker)(() => Log.Items.Add(ex.Message)));
return;
}
netStream = client.GetStream();
String path = "D:\\testingEnv\\test1\\testing\\Matematika\\2017\\Školsko\\2017-SS-skolsko-B-1234-zad.pdf";
String Filename = Path.GetFileName(path);
// We wish to send some data in advance:
// File name, file size, number of packets, send start and send end
byte[] data = File.ReadAllBytes(path);
// First packet contains: name size, file name, file size and "sendStart" signal
byte[] nameSize = BitConverter.GetBytes(Encoding.UTF8.GetByteCount(Filename)); // Int
byte[] nameB = Encoding.UTF8.GetBytes(Filename);
byte[] fileSize = BitConverter.GetBytes(data.Length);
byte[] start = Encoding.UTF8.GetBytes("sendStart");
// Last packet constains: "sendEnd" signal to stop reading netStream
byte[] end = Encoding.UTF8.GetBytes("sendEnd");
// Creating the first package: nameSize, fileName, fileSize and start signal
byte[] FirstPackage = new byte[4 + nameB.Length + 4 + 9];
nameSize.CopyTo(FirstPackage, 0);
nameB.CopyTo(FirstPackage, 4);
fileSize.CopyTo(FirstPackage, 4 + nameB.Length);
start.CopyTo(FirstPackage, 4 + nameB.Length + 4);
// Send the first pckage
netStream.Write(FirstPackage, 0, FirstPackage.Length);
byte[] buffer = new byte[30];
// Read the response
netStream.Read(buffer, 0, 11);
netStream.Close();
client.Close();
}
A friend tried to port forward the port 13000 but it didn't work either. We even tried with the firewall being down but nothing. I searched on the internet but couldn't find any solutions to the problem.
One thing to note is that both functions are in the same application. I don't know if that is the cause of the problem.
Does anyone know how what is the problem here?
Thanks in advance
Have you tried to connect to your server with telnet ? "telnet localhost 13000" or from other computer with correct ip and address nbr ? Try that while debugging your server code. If telnet works, then client code has some problem..

Server closes connection when client sends a message

I am trying to learn the server/client paradigm. I have created a server that listens for connection and input on given port.
My problem is that, when a client connects and sends a message, the server closes the connection, and stops listening for input. What I want, is that when a clients sends a message, the sever should not close the connection, but still keep getting input from the connected client. I know that I can only handle one client at a time, since I am not creating a Thread for each client, but this should not cause the server to close connection as soon as the client sends a message.
Here is my server code:
public void startServer() {
try {
IPAddress iAd = IPAddress.Parse("127.0.0.10");
TcpListener tcpListner = new TcpListener(iAd, 9000);
tcpListner.Start();
Console.WriteLine("The server is running on port: 9000");
Console.WriteLine("The local End point is: " + tcpListner.LocalEndpoint + "\nWaiting for a connection");
Socket socket = tcpListner.AcceptSocket();
Console.WriteLine("\nConnection from client: " + socket.RemoteEndPoint);
byte[] b =new byte[100];
int k = socket.Receive(b);
for (int i=0;i<k;i++) {
Console.Write("Recieved: " + Convert.ToChar(b[i]));
}
ASCIIEncoding asen=new ASCIIEncoding();
socket.Send(asen.GetBytes("The string was recieved by the server."));
Console.WriteLine("\nSent Acknowledgement");
/* clean up */
socket.Close();
tcpListner.Stop();
} catch(Exception e) {
Console.WriteLine(e.Message);
}
}
And the client code
public void StartClient(string servToConnectTo, int port) {
try{
client.Connect(servToConnectTo, port);
Console.WriteLine("Connected to server: " + servToConnectTo + " on port: " + port);
Console.WriteLine ("Write input to server...");
String input = Console.ReadLine();
Stream stream = client.GetStream();
ASCIIEncoding asen = new ASCIIEncoding();
byte[] b = asen.GetBytes(input);
Console.WriteLine("Sending...");
stream.Write(b, 0, b.Length);
byte[] bb = new byte[100];
int k = stream.Read(bb, 0, 100);
for(int i = 0; i < k; i++) {
Console.Write(Convert.ToChar(bb[i]));
}
client.Close();
} catch (Exception e) {
Console.WriteLine (e.Message);
}
}
I guess I need a while loop some place, but not sure where

UDP ping implementation in C#

I'm trying to implement ping based on udp packets with C#. The idea is to send udp packets to wrong port and get back ICMP packets contating Port unreachable error. And the time elapsed between seding the udp packet and recieveing the icmp packet is a ping time. I do it like that:
// Start building the headers
//Console.WriteLine("Building the packet header...");
int messageSize = 64;
byte[] builtPacket, payLoad = new byte[messageSize];
UdpHeader udpPacket = new UdpHeader();
ArrayList headerList = new ArrayList();
Socket rawSocket = null;
SocketOptionLevel socketLevel;
// Initialize the payload
//Console.WriteLine("Initialize the payload...");
for (int i = 0; i < payLoad.Length; i++)
payLoad[i] = (byte)'0';
// Fill out the UDP header first
//Console.WriteLine("Filling out the UDP header...");
udpPacket.SourcePort = 33434;
udpPacket.DestinationPort = 33434;
udpPacket.Length = (ushort)(UdpHeader.UdpHeaderLength + messageSize);
udpPacket.Checksum = 0;
Ipv4Header ipv4Packet = new Ipv4Header();
// Build the IPv4 header
//Console.WriteLine("Building the IPv4 header...");
ipv4Packet.Version = 4;
ipv4Packet.Protocol = (byte)ProtocolType.Udp;
ipv4Packet.Ttl = 30;
ipv4Packet.Offset = 0;
ipv4Packet.Length = (byte)Ipv4Header.Ipv4HeaderLength;
ipv4Packet.TotalLength = (ushort)Convert.ToUInt16(Ipv4Header.Ipv4HeaderLength + UdpHeader.UdpHeaderLength + messageSize);
ipv4Packet.SourceAddress = sourceAddress;
ipv4Packet.DestinationAddress = destAddress;
// Set the IPv4 header in the UDP header since it is required to calculate the
// pseudo header checksum
//Console.WriteLine("Setting the IPv4 header for pseudo header checksum...");
udpPacket.ipv4PacketHeader = ipv4Packet;
// Add IPv4 header to list of headers -- headers should be added in th order
// they appear in the packet (i.e. IP first then UDP)
//Console.WriteLine("Adding the IPv4 header to the list of header, encapsulating packet...");
headerList.Add(ipv4Packet);
socketLevel = SocketOptionLevel.IP;
// Add the UDP header to list of headers after the IP header has been added
//Console.WriteLine("Adding the UDP header to the list of header, after IP header...");
headerList.Add(udpPacket);
// Convert the header classes into the binary on-the-wire representation
//Console.WriteLine("Converting the header classes into the binary...");
builtPacket = udpPacket.BuildPacket(headerList, payLoad);
// Create the raw socket for this packet
//Console.WriteLine("Creating the raw socket using Socket()...");
rawSocket = new Socket(sourceAddress.AddressFamily, SocketType.Raw, ProtocolType.Udp);
// Bind the socket to the interface specified
//Console.WriteLine("Binding the socket to the specified interface using Bind()...");
IPAddress bindAddress = IPAddress.Any;
rawSocket.Bind(new IPEndPoint(bindAddress, 0));
// Set the HeaderIncluded option since we include the IP header
//Console.WriteLine("Setting the HeaderIncluded option for IP header...");
rawSocket.SetSocketOption(socketLevel, SocketOptionName.HeaderIncluded, 1);
rawSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 1000);
Stopwatch timer = new Stopwatch();
try {
for (int i = 0; i < 5; i++) {
timer.Reset();
timer.Start();
int rc = rawSocket.SendTo(builtPacket, new IPEndPoint(destAddress, 0));
Console.WriteLine("Sent {0} bytes to {1}", rc, destAddress);
Socket icmpListener = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);
icmpListener.Bind(new IPEndPoint(sourceAddress, 0));
icmpListener.IOControl(IOControlCode.ReceiveAll, new byte[] { 1, 0, 0, 0 }, new byte[] { 1, 0, 0, 0 });
icmpListener.Shutdown(SocketShutdown.Send);
byte[] buffer = new byte[4096];
EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
try {
int bytesRead = icmpListener.ReceiveFrom(buffer, ref remoteEndPoint);
timer.Stop();
Console.WriteLine("Recieved " + bytesRead + " bytes from " + destAddress + " in " + timer.ElapsedMilliseconds + "ms\n");
}
catch {
Console.WriteLine("Server is not responding!");
}
finally {
icmpListener.Close();
}
}
}
catch (SocketException err) {
Console.WriteLine("Socket error occurred: {0}", err.Message);
}
finally {
rawSocket.Close();
}
And it works from time to time. The thing is that some web-sites send me an icmp packet and some not. Actually at first they also were not sending then I used Windows ping to ping them and tracert to traceroute them. And changed port number and it worked. But not for all. I can ping only google.com and one more site but others don't send icmp packet back. The same situation with local network computers I tried to ping. I send udp packet and don't get icmp back.
I used wireshark to watch packets flying.
What am I doing wrong in here?

TCP/IP sending a string and receiving a string to a Robot controller using C#

I am trying to connect with a robot controller from PC using TCP/IP. The robot controller accepts only the ASCII string data from the PC (TCP Client). According to the Robot controller's command structure I have to send a particular string and get ACK from it to get the access.
I used the following code
try
{
System.Net.IPAddress IPADD = System.Net.IPAddress.Parse("192.168.255.2");
int PortNo = 80;
char[] ok = new char[33];
byte[] Data = new byte[33];
byte[] StartReq = new byte[21];
String Start = "CONNECT Robot_access";
// INITIALIZING TCP CLIENT
TcpClient TCP = new TcpClient();
Console.WriteLine("Connecting..........");
TCP.Connect(IPADD, PortNo);
Console.WriteLine("Connected");
NetworkStream NS = TCP.GetStream();
// START REQUEST
StartReq = Encoding.ASCII.GetBytes(Start);
NS.Write(StartReq, 0, StartReq.Length);
Console.WriteLine("start request send..........");
// RECEIVE ACK FOR ROBOT ACCESS
Int32 RespData = NS.Read(Data, 0, Data.Length);
string ACK = Encoding.ASCII.GetString(Data, 0, RespData);
Console.WriteLine("The ACK is {0} ", ACK);
Console.WriteLine("ACK Received");
Console.Read();
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace);
Console.Read();
}
I have aslo tried Streamwriter and Bufferstream to send and receive string couldn't succeed. My program runs through completely without any exception (except a 30s delay for Networkstream reading).

Socket Programming: Server/Clients and Thread Usage

static void Main(string[] args)
{
Console.Title = "Socket Server";
Console.WriteLine("Listening for client messages");
Socket serverSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
IPAddress serverIp = IPAddress.Any;
IPEndPoint serverEP = new IPEndPoint(serverIp, 8000);
SocketPermission socketPermission = new SocketPermission(NetworkAccess.Accept,
TransportType.Tcp,
"127.0.0.1", 8000);
serverSocket.Bind(serverEP);
serverSocket.Listen(2);
while(true)
{
//Socket connection = serverSocket.Accept();
connection = serverSocket.Accept();
Thread clientThread = new Thread(new ParameterizedThreadStart(MultiUser));
clientThread.Start(connection);
}
}
public static void MultiUser(object connection)
{
byte[] serverBuffer = new byte[10025];
string message = string.Empty;
int bytes = ((Socket)connection).Receive(serverBuffer, serverBuffer.Length, 0);
message += Encoding.ASCII.GetString(serverBuffer, 0, bytes);
Console.WriteLine(message);
TcpClient client = new TcpClient();
client.Client = ((Socket)connection);
IntPtr handle = client.Client.Handle;
}
I want to write a chat program which has one server and 2 clients. The problem is that, I can not direct the message sent from the client1 to client2 via the server. How can the server distinguish threads so that it can send the received message from client1 to client2?
Each client has their own handle. You can access this via the Handle property. For example:
TcpClient client = tcpListener.AcceptTcpClient();
IntPtr handle = client.Client.Handle; //returns a handle to the connection
Then all you need to do is store this in a hashtable, and iterate through it, looking for available data. When you detect data on the wire for one of the connections, then save it and retransmit it to the other clients in the table.
Remember to make sure that you make this multithreaded so a listen request on one client does not block any send or receive functions on other clients!
I've added some code here you should be able to work with (tested it out on my system)
private void HandleClients(object newClient)
{
//check to see if we are adding a new client, or just iterating through existing clients
if (newClient != null)
{
TcpClient newTcpClient = (TcpClient)newClient;
//add this client to our list
clientList.Add(newTcpClient.Client.Handle, newTcpClient);
Console.WriteLine("Adding handle: " + newTcpClient.Client.Handle); //for debugging
}
//iterate through existing clients to see if there is any data on the wire
foreach (TcpClient tc in clientList.Values)
{
if (tc.Available > 0)
{
int dataSize = tc.Available;
Console.WriteLine("Received data from: " + tc.Client.Handle); //for debugging
string text = GetNetworkString(tc.GetStream());
//and transmit it to everyone else
foreach (TcpClient otherClient in clientList.Values)
{
if (tc.Client.Handle != otherClient.Client.Handle)
{
Send(otherClient.GetStream(), text);
}
}
}
}
}
public void Send(NetworkStream ns, string data)
{
try
{
byte[] bdata = GetBytes(data, Encoding.ASCII);
ns.Write(bdata, 0, bdata.Length);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}
}
protected string GetNetworkString(NetworkStream ns)
{
if (ns.CanRead)
{
string receivedString;
byte[] b = GetNetworkData(ns);
receivedString = System.Text.Encoding.UTF8.GetString(b);
log.Info("Received string: " + receivedString);
return receivedString;
}
else
return null;
}
protected byte[] GetNetworkData(NetworkStream ns)
{
if (ns.CanRead)
{
log.Debug("Data detected on wire...");
byte[] b;
byte[] myReadBuffer = new byte[1024];
MemoryStream ms = new MemoryStream();
int numberOfBytesRead = 0;
// Incoming message may be larger than the buffer size.
do
{
numberOfBytesRead = ns.Read(myReadBuffer, 0, myReadBuffer.Length);
ms.Write(myReadBuffer, 0, numberOfBytesRead);
}
while (ns.DataAvailable);
//and get the full message
b = new byte[(int)ms.Length];
ms.Seek(0, SeekOrigin.Begin);
ms.Read(b, 0, (int)ms.Length);
ms.Close();
return b;
}
else
return null;
}
You will want to call HandleClients from a main thread that checks to see if there are any pending requests or not, and runs on a loop.

Categories

Resources