Message not received TCP - c#

My IP-Camera is configured to send alarm messages to my computer.
IPAddress of camera: 10.251.51.1
IPAddress of my computer: 10.251.51.136
The camera can be configured to send messages to any port on my computer.
So, I set the alarm destination to my computer's IP Address: 10.251.51.136 at port 3487.
Now, what should be done at my computer to get the message sent by the camera ?
I tried to write a TCPListener from MSDN and the code is below:
Int32 port = 3487;
IPAddress localAddr = IPAddress.Parse("10.251.51.136");
// TcpListener server = new TcpListener(port);
server = new TcpListener(localAddr, port);
server.Start();
// Start listening for client requests.
// Buffer for reading data
Byte[] bytes = new Byte[256];
String data = null;
// Enter the listening loop.
while (true)
{
Console.Write("Waiting for a connection... ");
// Perform a blocking call to accept requests.
// You could also user server.AcceptSocket() here.
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("Connected!");
server.Start();
data = null;
// Get a stream object for reading and writing
NetworkStream stream = client.GetStream();
int i;
// Loop to receive all the data sent by the client.
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
// Translate data bytes to a ASCII string.
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine("Received: {0}", data);
// Process the data sent by the client.
data = data.ToUpper();
byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);
// Send back a response.
stream.Write(msg, 0, msg.Length);
Console.WriteLine("Sent: {0}", data);
}
// Shutdown and end connection
client.Close();
}
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
finally
{
// Stop listening for new clients.
server.Stop();
}
But this does not seem to be working.
Or is my entire approach flawed ? Should i implement TCPListener or TCPServer instead for my scenario above?
Any pointers why?

Related

Why my server program prints the first letter of the message I sent from client in C#?

I am trying to send a message from a Socket client I created in C# on an Android device to a TCPListener server on my PC. The message is sent and I can see it printed on the output of the terminal as I programmed it to but now the server prints the first letter of the message only like when I send David, it only prints D. I need help to revise my code and make it print the entire message sent from the Android client. The code for the server program is below
static void Main(string[] args)
{
TcpListener server = null;
try
{
//decide where the aplication will listen for connections
int port = 13000;
IPAddress localAddress = IPAddress.Parse("192.168.49.147");
server = new TcpListener(localAddress, port);
//start listening for client requests
server.Start();
//initialize buffer for reading data received from a client
byte[] bytes = new byte[256];
string? data;
data = null;
//enter into the listening loop
while (true)
{
Console.WriteLine("Listening for connections");
//perform a blocking call to accept requests
//You could also use a server.Accept() to accept an incoming connection
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("Connected");
data = null;
//get a stream object for reading and writing
NetworkStream stream = client.GetStream();
int i;
//loop to receive all the data
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
//translate the byte received into ASCII encoded data
//something is wrong here as it prints the first character of the string
data = System.Text.Encoding.ASCII.GetString(bytes, 0, 1);
Console.WriteLine("Received: {0}", data);
//process the data sent ny the client
data.ToUpper();
byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);
// Send back a response.
stream.Write(msg, 0, msg.Length);
Console.WriteLine("Sent: {0}", data);
}
//shut down and end connection
client.Close();
}
}catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
//stop listening for new connections
server.Stop();
}
}

Tcp connection fails on LAN

I am trying to send a message from my laptop to my desktop over the LAN.
I have written a Tcp server that listens for a connection on a port, and a client that tries to connect to it and send a simple string as a message.
Server:
void Listen()
{
listener = new TcpListener(IPAddress.Any, port);
listener.Start();
while (true)
{
Debug.Log($"listening to {listener.LocalEndpoint}...");
var socket = listener.AcceptSocket();
Debug.Log("connected!");
var bytes = new byte[100];
int k = socket.Receive(bytes);
var data = Encoding.ASCII.GetString(bytes, 0, k);
Debug.Log(data);
socket.Send(new byte[] {1});
Debug.Log("responded");
socket.Close();
Debug.Log("closed connection");
}
}
Client:
public void Send()
{
client = new TcpClient();
Debug.Log("connecting...");
client.Connect("192.168.0.12", port);
Debug.Log("connected!");
var data = Encoding.ASCII.GetBytes("Hello!");
var stream = client.GetStream();
Debug.Log("sending data");
stream.Write(data, 0, data.Length);
Debug.Log("data sent! waiting for response...");
var reply = new byte[100];
stream.Read(reply,0,100);
Debug.Log("received response");
client.Close();
}
They communicate correctly when they are both on the same machine, but the client never connects to the server when I am running it on a different machine.
I have a rule in my firewall that allows an incoming connection through the port I have specified.
I have tried it with both computer's firewalls off and the connection still doesn't go through.
Any help would be greatly appreciated.

C# one tcp networkstream accepted

I have an issue with a TCP Listener.
The scenario is the following:
- I am receiving TCP packets (8192 Bytes each) and I would like to dump the data received from NetworkStream into a file (using FileStream);
- What I saw is that all the TCP packets arrived to the TCP listener but only the first 8192 Bytes are dumped into the file.
I believe that the NetStream is faster than the IO operation to the file.
My code is:
try
{
// Set TcpListener on port 8
Int32 portN = 8;
TcpListener server = new TcpListener(IPAddress.Any, portN);
// Start listening for client requests
server.Start();
Console.Write("Waiting for connection... ");
// Define File Name
string RcvFileName = #"c:\ethernet\out_file.raw";
// Buffer for reading data
int NrBytesRec;
Byte[] RecData = new Byte[8192];
// enter into listening loop
while (true)
{
// Perform a blocking call to accept requests.
// You can also user server.AcceptSocket() here.
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("Connected!");
// Get a stream object for reading and writing
NetworkStream netstream = client.GetStream();
// Append data into file
FileStream fs_wr = new FileStream(RcvFileName, FileMode.Append, FileAccess.Write);
// Dump data
while ((NrBytesRec = netstream.Read(RecData, 0, RecData.Length)) > 0)
{
fs_wr.Write(RecData, 0, NrBytesRec);
Console.WriteLine("Received: {0}", NrBytesRec);
}
netstream.Close();
fs_wr.Close();
//client.Close();
}

Send text string via TCP?

I just read and tested code of this great article in order to understand TCP Client and Server.
Now I need to do (I hope) really simple thing I need to send some string from TCP Client To TCP Server.
The string is serialized object and it is a XML in fact.
What I don't understand where I have to include this code in TCP Client and also in the TCP server.
TCP Client:
static void Main(string[] args)
{
while (true)
{
String server = "192.168.2.175"; // args[0]; // Server name or IP address
// Convert input String to bytes
byte[] byteBuffer = Encoding.ASCII.GetBytes("1024"); // Encoding.ASCII.GetBytes(args[1]);
// Use port argument if supplied, otherwise default to 8080
int servPort = 1311; // (args.Length == 3) ? Int32.Parse(args[2]) : 8080;//7 ;
TcpClient client = null;
NetworkStream netStream = null;
try
{
// Create socket that is connected to server on specified port
client = new TcpClient(server, servPort);
Console.WriteLine("Connected to server... sending echo string");
netStream = client.GetStream();
// Send the encoded string to the server
netStream.Write(byteBuffer, 0, byteBuffer.Length);
Console.WriteLine("Sent {0} bytes to server...", byteBuffer.Length);
int totalBytesRcvd = 0; // Total bytes received so far
int bytesRcvd = 0; // Bytes received in last read
// Receive the same string back from the server
while (totalBytesRcvd < byteBuffer.Length)
{
if ((bytesRcvd = netStream.Read(byteBuffer, totalBytesRcvd,
byteBuffer.Length - totalBytesRcvd)) == 0)
{
Console.WriteLine("Connection closed prematurely.");
break;
}
totalBytesRcvd += bytesRcvd;
}
Console.WriteLine("Received {0} bytes from server: {1}", totalBytesRcvd,
Encoding.ASCII.GetString(byteBuffer, 0, totalBytesRcvd));
}
catch (Exception ex)
{
// http://stackoverflow.com/questions/2972600/no-connection-could-be-made-because-the-target-machine-actively-refused-it
Console.WriteLine(ex.Message);
}
finally
{
if (netStream != null)
netStream.Close();
if (client != null)
client.Close();
}
Thread.Sleep(1000);
}
}
TCP Server
class Program
{
private const int BUFSIZE = 32; // Size of receive buffer
static void Main(string[] args)
{
int servPort = 1311; // (args.Length == 1) ? Int32.Parse(args[0]) : 8080;
TcpListener listener = null;
try
{
// Create a TCPListener to accept client connections
listener = new TcpListener(IPAddress.Any, servPort);
listener.Start();
}
catch (SocketException se)
{
// IPAddress.Any
Console.WriteLine(se.ErrorCode + ": " + se.Message);
//Console.ReadKey();
Environment.Exit(se.ErrorCode);
}
byte[] rcvBuffer = new byte[BUFSIZE]; // Receive buffer
int bytesRcvd; // Received byte count
for (; ; )
{ // Run forever, accepting and servicing connections
// Console.WriteLine(IPAddress.Any);
TcpClient client = null;
NetworkStream netStream = null;
//Console.WriteLine(IPAddress.None);
try
{
client = listener.AcceptTcpClient(); // Get client connection
netStream = client.GetStream();
Console.Write("Handling client - ");
// Receive until client closes connection, indicated by 0 return value
int totalBytesEchoed = 0;
while ((bytesRcvd = netStream.Read(rcvBuffer, 0, rcvBuffer.Length)) > 0)
{
netStream.Write(rcvBuffer, 0, bytesRcvd);
totalBytesEchoed += bytesRcvd;
}
Console.WriteLine("echoed {0} bytes.", totalBytesEchoed);
// Close the stream and socket. We are done with this client!
netStream.Close();
client.Close();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
netStream.Close();
}
}
}
}
Converting my Comments into an answer:
I strongly suggest you use WCF, instead of implementing all the stuff yourself. In WCF, you create the interfaces (Service Contracts) and implementations (Services) and the framework abstracts all the communication / protocol details out.
You can use WCF Duplex to have two-way communications between server and client
The example that you give is a simple 'mirror', where the TCP server sends back to the client the data that it receives from it.
The data that you want to send is in the byteBuffer variable (you are currently sending the text "1024", I believe). So instead of initializing it with "1024", you could initialize it with the XML-serialized data that you want.
On the client side, conversely, instead of echoing the data back to the client, you could simply do whatever you need on the server side with the data, that is your XML object.

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.

Categories