Receiving null byte array from simulator - c#

This is my code for a client to receive data from a server which is the simulator. While debugging the code, I received null values in this array, called receivedBytes:
// define buffer
byte[] receivedBytes = new byte[2048];
// define endpoint
IPHostEntry ipHost = Dns.Resolve("192.168.1.55");
IPAddress ipAddress = ipHost.AddressList[0];
IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 1001);
// connect
Console.WriteLine("Starting: Creating Socket object");
Socket sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sender.Connect(ipEndPoint);
Console.WriteLine("Successfully connected to {0}", sender.RemoteEndPoint);
// get user input
Console.WriteLine("Enter Client Message :");
string sendingMessage = Console.ReadLine();
// send
Console.WriteLine("Creating message:{0}", sendingMessage);
byte[] forwardMessage = Encoding.Default.GetBytes(sendingMessage);
sender.Send(forwardMessage);
// receive
int totalBytesReceived = sender.Receive(receivedBytes);
Console.WriteLine("Message provided from server: {0}", Encoding.Unicode.GetString(receivedBytes, 0, totalBytesReceived));
// close
sender.Shutdown(SocketShutdown.Both);
sender.Close();
Console.ReadLine();
What am I doing wrong here?

Actually the conversion code is wrong.
string sendingMessage = "Hello, World";
byte[] forwardMessage = Encoding.Default.GetBytes(sendingMessage);
string receivedMessage = Encoding.Unicode.GetString(forwardMessage, 0,forwardMessage.Length);
After that receivedMessage will be broken.
What it does? It gets default encoding to GetBytes and than uses UTF-16 encoding to get string. You should use Encoding.Default.GetBytes and Encoding.Default.GetString.

Related

Server client communication using Socket C#

I have created an application, which is communicating a server using IP/port. It is sending a ISO request string(Bitmaps in ASCII format) and receiving a response string same format. While Sending the bytes through socket.send and receiving the bytes in socket.receive method. I can see extended ASCII characters are getting changed on other side (Server side/Clint side). I am using below code. Can anyone suggest please, How to resolve the issue.
IPAddress ipAddr = IPAddress.Parse("10.03.0.18");
IPEndPoint localEndPoint = new IPEndPoint(ipAddr, 12345);
// Creation TCP/IP Socket using
// Socket Class Costructor
Socket sender = new Socket(ipAddr.AddressFamily,SocketType.Stream, ProtocolType.Tcp);
sender.Connect(localEndPoint);
string requeststring = AccountValidationRequest();
byte[] messageSent = Encoding.ASCII.GetBytes(requeststring);
int byteSent = sender.Send(messageSent);
byte[] ServerResponse = new byte[1024];
int byteRecv = sender.Receive(ServerResponse);
string ISO8583Message = Encoding.ASCII.GetString(ServerResponse, 0, byteRecv);
Console.WriteLine("Response received from server: --> :{0}", Encoding.ASCII.GetString(ServerResponse, 0, byteRecv));
As it was suggested in comments you should assert that you read all data, not only the first chunk.
Byte[] bytesReceived = new Byte[256];
int bytes = 0;
var ISO8583Message = "Response: \n";
do {
bytes = sender.Receive(bytesReceived, bytesReceived.Length, 0);
ISO8583Message = ISO8583Message + Encoding.ASCII.GetString(bytesReceived, 0, bytes);
}
while (bytes > 0);
There are some nice examples with using sockets on https://learn.microsoft.com/pl-pl/dotnet/api/system.net.sockets.socket?view=netframework-4.8.

Discovering Lantronix XPort Pro and XPort using C# sockets

I am trying to find Lantronix XPort Pro devices on a network using C#. I am using some python code that I found on the Lantronix developer wiki as an example http://wiki.lantronix.com/developer/Lantronix_Discovery_Protocol.
The application I am writing is written in C# and I need to discover our units that have Lantronix devices installed. It seems that when I do the socket.RecieveFrom function call it just seems to hang the app.
Any ideas on what I am doing wrong. The python code from the link above detects the devices correctly. I should be able to duplicate this in C#.
Any help would be much appreciated.
private void FindLantronixXPort()
{
// This is the socket code that will broadcast from
// the local machine looking for responces from Lantronix
// XPort servers
// Create the array for our message chars
char[] chars = new char[4];
// Build the actual message
chars[0] = Convert.ToChar(0);
chars[1] = Convert.ToChar(0);
chars[2] = Convert.ToChar(0);
chars[3] = Convert.ToChar(0xf6);
// Convert the chars to a message string
string msg = new string(chars);
// Convert the setring to a byte array
byte[] data = Encoding.UTF8.GetBytes(msg);
// Get the local machines IP address
string Local_IP = GetIPAddress();
// Now create a broadcast UDP socket
Socket XmtSock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
XmtSock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
IPEndPoint iep = new IPEndPoint(IPAddress.Parse(Local_IP), LantronixPort);
// Broadcast the packet
XmtSock.SendTo(data, 0, data.Length, SocketFlags.None, iep);
XmtSock.Close();
// Wait 500 mili seconds
int milliseconds = 500;
System.Threading.Thread.Sleep(milliseconds);
Socket RcvSock = new Socket(AddressFamily.InterNetwork,
SocketType.Dgram, ProtocolType.Udp);
iep = new IPEndPoint(IPAddress.Any, LantronixPort);
RcvSock.Bind(iep);
EndPoint ep = (EndPoint)iep;
Console.WriteLine("Ready to receive...");
byte[] data1 = new byte[120];
int recv = RcvSock.ReceiveFrom(data1, data1.Length, SocketFlags.None, ref ep);
string stringData = Encoding.ASCII.GetString(data1, 0, recv);
Console.WriteLine("received: {0} from: {1}",
stringData, ep.ToString());
RcvSock.Close();
}
Lantronix's wiki seems to be down at the moment, so I can't take a look at that for the moment. However, looking at your code it seems that you have to broadcast a UDP message, wait some time, and then check to see if anything has responded to that message.
However, it looks like you're creating a brand new socket for receiving the responses, but only after half a second. It's highly likely that any X-port that is going to respond will already have done so long before then (networks are fast, X-ports aren't very sluggish, etc). So I reckon the responses are hitting your OS'es network stack, which saying "well I dunno where that's supposed to go", and only after half a second are you creating a socket suitable for receiving the responses that the OS'es network stack has already discarded as unknown junk.
So move things around a bit is what I suggest. Set up the receiving socket, binding and endpoint before you transmit the broadcast message, so that it's ready there waiting for responses. See if that helps.
#WJD Your code for preparing byte array did not create content expected by XPort. It is why it did not replyed and hang on RecieveFrom().
I followed the link you gave for python example and created version in C#.
class Program
{
static void Main(string[] args)
{
Socket socket;
int GroupPort = 30718;
try
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);
var localEP = new IPEndPoint(IPAddress.Parse("10.0.2.14"), GroupPort); // <-- your local IP address
socket.Bind(localEP);
socket.ReceiveTimeout = 200;
}
catch (TimeoutException e)
{
Console.WriteLine("Failed to create socket. " + e.Message);
return;
}
var remoteEP = new IPEndPoint(IPAddress.Broadcast, GroupPort);
try
{
byte[] messageBytes;
messageBytes = new byte[0];
messageBytes = AddByteToArray(messageBytes, 0xf6);
messageBytes = AddByteToArray(messageBytes, 0);
messageBytes = AddByteToArray(messageBytes, 0);
messageBytes = AddByteToArray(messageBytes, 0);
socket.SendTo(messageBytes, remoteEP);
}
catch (Exception e)
{
Console.WriteLine("Failed to send message. " + e.Message);
return;
}
var recvEp = (EndPoint)new IPEndPoint(IPAddress.Any, 0);
while (true)
{
try
{
var recvBytes = new byte[1024];
var receivedCount = socket.ReceiveFrom(recvBytes, ref recvEp);
var receivedArray = recvBytes.Take(receivedCount).ToArray();
var receivedArrayAsHexString = string.Join("", receivedArray.Select(c => String.Format("{0:X2}", Convert.ToInt32(c))));
string returnData = Encoding.ASCII.GetString(receivedArray);
Console.WriteLine($"Broadcast Respond from client {recvEp.ToString()} returned: {receivedArrayAsHexString}");
}
catch (Exception e)
{
socket.Close();
break;
}
}
Console.ReadLine();
}
public static byte[] AddByteToArray(byte[] bArray, byte newByte)
{
byte[] newArray = new byte[bArray.Length + 1];
bArray.CopyTo(newArray, 1);
newArray[0] = newByte;
return newArray;
}
}

C# send custom socket string

I have this code:
public static List<Socket> samp = new List<Socket>();
IPHostEntry host = null;
Socket sock;
host = Dns.GetHostEntry(sending ip..);
foreach (IPAddress address in host.AddressList)
{
IPEndPoint ipe = new IPEndPoint(address, 7777);
sock = new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
sock.Connect(ipe);
if (sock.Connected)
{
samp.Add(sock);
}
}
This code work's okay. It send's my ip. How it looks in console:
How can I send custom string? For example i'm tried this code:
if (sock.Connected)
{
byte[] msg = Encoding.UTF8.GetBytes("This is a test");
byte[] bytes = new byte[256];
int i = sock.Send(msg);
MessageBox.Show(string.Format("Sent {0} bytes.", i));
samp.Add(sock);
}
It shows message: Sent 14 bytes. But in the console nothing prints.. How can I send this text to console? I'm also tried this:
sock.Send(Encoding.UTF8.GetBytes("This is a test"));
And this not prints :(
Thanks in advance !

Sending long XML over TCP

I'm sending an object (class name House) over TCP using the TcpListener on the server side in response to any message received from the TcpClient.
When the message is received, it is currently populating a text box named textBox1.
If I send a line of text, it works fine. You'll notice that I have a redundant line "Hello, I'm a server" for testing this purpose. But when I send the XML, it is cutting it off prematurely.
When I send serialised XML in to the stream, I'm also receiving this error from the server side:
Unable to read data from the transport connection: An existing
connection was forcibly closed by the remote host.
Here's my server code
// Set the variables for the TCP listener
Int32 port = 14000;
IPAddress ipaddress = IPAddress.Parse("132.147.160.198");
TcpListener houseServer = null;
// Create IPEndpoint for connection
IPEndPoint ipend = new IPEndPoint(ipaddress, port);
// Set the server parameters
houseServer = new TcpListener(port);
// Start listening for clients connecting
houseServer.Start();
// Buffer for reading the data received from the client
Byte[] bytes = new Byte[256];
String data = "hello, this is a house";
// Show that the TCP Listener has been initialised
Console.WriteLine("We have a TCP Listener, waiting for a connection...");
// Continuing loop looking for
while (true)
{
// Create a house to send
House houseToSendToClient = new House
{
house_id = 1,
house_number = 13,
street = "Barton Grange",
house_town = "Lancaster",
postcode = "LA1 2BP"
};
// Get the object serialised
var xmlSerializer = new XmlSerializer(typeof(House));
using (var memoryStream = new MemoryStream())
{
xmlSerializer.Serialize(memoryStream, houseToSendToClient);
}
// Accept an incoming request from the client
TcpClient client = houseServer.AcceptTcpClient();
// Show that there is a client connected
//Console.WriteLine("Client connected!");
// Get the message that was sent by the server
NetworkStream stream = client.GetStream();
// Blank int
int i;
// Loop for receiving the connection from the client
// >>> ERROR IS ON THIS LINE <<<
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
Console.WriteLine("here");
// Take bytes and convert to ASCII string
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine("Received s, return house");
// Convert the string to a byte array, ready for sending
Byte[] dataToSend = System.Text.Encoding.ASCII.GetBytes("Hello, I'm a server");
// Send the data back to the client
//stream.Write(dataToSend, 0, dataToSend.Length);
// Send serialised XML in to the stream
xmlSerializer.Serialize(stream, houseToSendToClient);
}
// Close the connection
client.Close();
}
Client code
// Get the object serialised
var xmlSerializer = new XmlSerializer(typeof(House));
// Set the variables for the TCP client
Int32 port = 14000;
IPAddress ipaddress = IPAddress.Parse("127.0.0.1");
IPEndPoint ipend = new IPEndPoint(ipaddress, port);
string message = "s";
try
{
// Create TCPCLient
//TcpClient client = new TcpClient("localhost", port);
TcpClient client = new TcpClient();
// Convert the string to a byte array, ready for sending
Byte[] dataToSend = System.Text.Encoding.ASCII.GetBytes(message);
// Connect using TcpClient
client.Connect(ipaddress, port);
// Client stream for reading and writing to server
NetworkStream stream = client.GetStream();
// Send the data to the TCP Server
stream.Write(dataToSend, 0, dataToSend.Length);
//xmlSerializer.Serialize(stream, houseToSend);
// Buffer to store response
Byte[] responseBytes = new Byte[256];
string responseData = String.Empty;
// Read the response back from the server
Int32 bytes = stream.Read(responseBytes, 0, responseBytes.Length);
responseData = System.Text.Encoding.ASCII.GetString(responseBytes, 0, bytes);
textBox1.Text = responseData;
// Close the stream and the client connection
stream.Close();
client.Close();
}
catch (SocketException e)
{
MessageBox.Show(e.ToString());
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
I've marked on the code where the error is appearing.
Is it because the message is too long?
Your client code is assuming that the entire message will come through in one call to the Read(...) method, which is absolutely wrong. From the MSDN docs: "An implementation is free to return fewer bytes than requested even if the end of the stream has not been reached."
It's possible that, for a 1024-byte XML document, you may have to call Read(...) 1024 times to get the entire message.
Really, you'd do well to send a four-byte length before you send the XML, so that the client knows how much data to expect. The client will read four bytes, convert that to an integer length, then read that many more bytes, then turn those bytes into XML.

UDP client in C#

Am trying to make a simple UDP application using C sharp,nothing sophisticated,connect,send some text,and receive it! but it keeps throwing this exception!
"An existing connection was forcibly closed by the remote host"!
The code :
byte[] data = new byte[1024];
IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9050);
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
string welcome = "Hello, are you there?";
data = Encoding.ASCII.GetBytes(welcome);
server.SendTo(data, data.Length, SocketFlags.None, ipep);
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
EndPoint tmpRemote = (EndPoint)sender;
data = new byte[1024];
int recv = server.ReceiveFrom(data, ref tmpRemote);
Console.WriteLine("Message received from {0}:", tmpRemote.ToString());
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
Console.WriteLine("Stopping client");
server.Close();
thanks =)
You should tell the system that you are listening for UDP packets on port 9050 before you call Receive.
Add server.Bind(ipep); after Socket server = new Socket(...);
Have you tried checking that the IP address is valid and the port is not being used for something else?
Windows:
Start > Run > "cmd" > "ipconfig".
Try turning off your firewall software.
If you do not know the IP of the answering server, you better do:
recv = server.Receive(data);
Here is my suggetion to your code. You can use a do-while loop using a condition (in my example it is an infinite loop):
byte[] data = new byte[1024];
IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9050);
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
string welcome = "Hello, are you there?";
data = Encoding.ASCII.GetBytes(welcome);
server.ReceiveTimeout = 10000; //1second timeout
int rslt = server.SendTo(data, data.Length, SocketFlags.None, ipep);
data = new byte[1024];
int recv = 0;
do
{
try
{
Console.WriteLine("Start time: " + DateTime.Now.ToString());
recv = server.Receive(data); //the code will be stoped hier untill the time out is passed
}
catch { }
} while (true); //carefoul! infinite loop!
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
Console.WriteLine("Stopping client");
server.Close();

Categories