C# I am developing a MIP plugin for Milestone VMS.
I have a problem while connecting to SocketIO with C#.
I have tried to connect to SocketIO with TcpClient, Socket, ClientWebSocket
TcpClient tcpClient = new TcpClient();
tcpClient.Connect("127.0.0.1, 3001);
I also have tried to connect with ClientWebSocket but again no reaction in server side.
using (var client = new ClientWebSocket())
{
// await client.ConnectAsync(new Uri("ws://192.168.100.25:8090/?token="),timeout.Token);
await client.ConnectAsync(new Uri(LOCAL_PATH), timeout.Token);
var buffer = new ArraySegment<byte>(new byte[1000]);
var result = await client.ReceiveAsync(buffer, timeout.Token);
}
Can anyone provide some libraries that may serve as clients to SocketIO?
URI has this syntax: http://127.0.0.1:3001?token=xxx
here is a tested code that i use , supposing your server is running , you need to pass the IP or HostName and port number , then come the payload or message that you want to send :
private bool ConnectAndSendMessage(String server, Int32 port, String message)
{
try
{
// Create a TcpClient.
TcpClient client = new TcpClient(server, port);
// Translate the passed message into ASCII and store it as a Byte array.
Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
// Get a client stream for reading and writing.
NetworkStream stream = client.GetStream();
// Send the message to the connected TcpServer.
stream.Write(data, 0, data.Length);
// Buffer to store the response bytes receiver from the running server.
data = new Byte[256];
// String to store the response ASCII representation.
String responseData = String.Empty;
// Read the first batch of the TcpServer response bytes.
Int32 bytes = stream.Read(data, 0, data.Length);
responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
// Close everything.
stream.Close();
client.Close(); return true;
}
catch (ArgumentNullException e)
{
_txtStyling.WriteCustomLine(string.Format("ArgumentNullException: {0} \n\n", e.Message), 14, false, false, Brushes.Red); return false;
}
catch (SocketException e)
{
_txtStyling.WriteCustomLine(string.Format("SocketException: {0} \n\n", e.Message), 14, false, false, Brushes.Red); return false;
}
}
Related
I'll try and explain my question below, I have tried googling for an answer but firstly, I don't really know what I should be googling and I haven't found anything that makes sense to me, I was wondering if someone could explain it? Many Thanks.
Hello. I am trying to send a simple network packet using TCP, I have done it using UDP pretty easily as its really easy with UDP, I was wondering if anyone could help me do the equivalent in TCP? I tried using a TcpClient, but it doesn't have a Send method the same as UDP?
public void OnUdp()
{
var client = new UdpClient(Host, Port);
client.Send(rubbish, rubbish.Length);
}
This is the example from https://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.aspx
static void Connect(String server, String message)
{
try
{
// Create a TcpClient.
// Note, for this client to work you need to have a TcpServer
// connected to the same address as specified by the server, port
// combination.
Int32 port = 13000;
TcpClient client = new TcpClient(server, port);
// Translate the passed message into ASCII and store it as a Byte array.
Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
// Get a client stream for reading and writing.
// Stream stream = client.GetStream();
NetworkStream stream = client.GetStream();
// Send the message to the connected TcpServer.
stream.Write(data, 0, data.Length);
Console.WriteLine("Sent: {0}", message);
// Receive the TcpServer.response.
// Buffer to store the response bytes.
data = new Byte[256];
// String to store the response ASCII representation.
String responseData = String.Empty;
// Read the first batch of the TcpServer response bytes.
Int32 bytes = stream.Read(data, 0, data.Length);
responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
Console.WriteLine("Received: {0}", responseData);
// Close everything.
stream.Close();
client.Close();
}
catch (ArgumentNullException e)
{
Console.WriteLine("ArgumentNullException: {0}", e);
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
Console.WriteLine("\n Press Enter to continue...");
Console.Read();
}
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?
I'm a Java Developer Trying to build a Simple C# TCP Client. however for the life of me I can't figure out how to get this bloody thing to work. Here is my TCPClient code. BTW, I stole this directly from msdn. http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.aspx
public static void Connect(String server, int port, String message)
{
try
{
// Create a TcpClient.
// Note, for this client to work you need to have a TcpServer
// connected to the same address as specified by the server, port
// combination.
TcpClient client = new TcpClient(server, port);
// Translate the passed message into ASCII and store it as a Byte array.
Byte[] data = Encoding.ASCII.GetBytes(message);
// Get a client stream for reading and writing.
// Stream stream = client.GetStream();
NetworkStream stream = client.GetStream();
// Send the message to the connected TcpServer.
stream.Write(data, 0, data.Length);
Console.WriteLine("Sent: {0}", message);
// Receive the TcpServer.response.
// Buffer to store the response bytes.
data = new Byte[256];
// String to store the response ASCII representation.
String responseData = String.Empty;
// Read the first batch of the TcpServer response bytes.
Int32 bytes = stream.Read(data, 0, data.Length);
responseData = Encoding.ASCII.GetString(data, 0, bytes);
Console.WriteLine("Received: {0}", responseData);
// Close everything.
stream.Close();
client.Close();
}
catch (ArgumentNullException e)
{
Console.WriteLine("ArgumentNullException: {0}", e);
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
Console.WriteLine("\n Press Enter to continue...");
Console.Read();
}
Here is my Java Server.
private ServerSocket socket;
private JAXBContext jaxbContext;
boolean listening = true;
#SuppressWarnings("unused")
private HMSAgentService() {
}
public HMSAgentService(int port) {
try {
this.socket = new ServerSocket(port);
logger.debug("Agent Service listening on port : " + port);
this.jaxbContext = HMSAgentUtil.getJAXBContext();
while (listening) {
new AgentServiceThread(socket.accept(), jaxbContext).start();
}
} catch (IOException e) {
logger.error(e.getMessage(), e);
} catch (JAXBException e) {
logger.error(e.getMessage(), e);
}
}
It simply starts off a new thread when it receives a client connection.
Now my problem is that The program never moves past the stream.Write(). Also the server never receives the message. Only after I call Stream.close() does the server receive the message. But that essentially closes the connection and the client can't receive any more messages. Why is happening. I've tried using Sockets, StreamWriters, StreamReaders and its the same story.
At this point i'm contemplating using The Asynchronous method, but I'm trying to keep the program as simple as possible, since there is no need for it. Is there anyway of signaling the end of a Write?
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.
I'm incredibly confused as to what is going on here. I've been putting in break points and I just can't seem to understand. Basically, I have a client and a server. I want the client to send two separate strings of data. From putting in break points, I noticed that my client does in fact fill both strings with the appropriate data. However, the server never ever sees the second string. Why is this happening and how do I fix it? Any help at all would be greatly appreciate! Below is my code:
Server:
private static void HandleClientComm(object client)
{
/** creating a list which contains DatabaseFile objects **/
List<DatabaseFile> theDatabase = new List<DatabaseFile>();
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
StringBuilder response = new StringBuilder();
byte[] message = new byte[4096];
int bytesRead;
do
{
bytesRead = 0;
try
{
/*do
{
bytesRead = clientStream.Read(message, 0, message.Length);
response.Append(Encoding.ASCII.GetString(message, 0, bytesRead));
} while (clientStream.DataAvailable);*/
when i change this commented code to bytesRead = clientStream.Read(message, 0, 4096); i get an IOException Error that reads as follows: Unable to write data to the transport connection: An existing connection was forcibly closed by the remote host. Hence, i changed it to a do while loop. How do i get around this IOException and accept the second string?
ASCIIEncoding encoder = new ASCIIEncoding();
String file = encoder.GetString(message, 0, bytesRead);
Menu.Insert(theDatabase, file);
}
catch (Exception)
{
// A socket error has occured
break;
}
if (bytesRead == 0)
{
// The client has disconnected from the server
break;
}
} while (clientStream.DataAvailable);
// Release connections
clientStream.Close();
tcpClient.Close();
}
Client:
static void Main(string[] args)
{
TcpClient client = new TcpClient();
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8888);
client.Connect(serverEndPoint);
NetworkStream clientStream = client.GetStream();
NetworkStream clientStream2 = client.GetStream();
ASCIIEncoding encoder = new ASCIIEncoding();
ASCIIEncoding encoder2 = new ASCIIEncoding();
String text = System.IO.File.ReadAllText("FirstNames.txt");
String text2 = System.IO.File.ReadAllText("LastNames.txt");
byte[] buffer = encoder.GetBytes(text);
Console.ReadLine();
clientStream.Write(buffer, 0, buffer.Length);
clientStream.Flush();
Console.ReadLine();
byte[] buffer2 = encoder2.GetBytes(text2);
clientStream2.Write(buffer2, 0, buffer2.Length);
clientStream2.Flush();
Console.ReadLine();
}
}
The communication between client and server happens like this (note that the order of steps is just for illustration purposes, the actual order at runtime may be different):
Client: client.Connect(serverEndPoint)
Server: HandleClientComm(newClient)
Client: clientStream.Write(buffer, 0, buffer.Length)
Server: bytesRead = clientStream.Read(message, 0, message.Length)
Note that Read is not guaranteed to read entire message. It is perfectly ok to return just the portion that has been received so far
Client: Console.ReadLine()
Server: while (clientStream.DataAvailable)
There is no data on the stream - the client has not sent any. This would likely happen even without ReadLine - there is a window of time before the client sends data again
Server: tcpClient.Close()
Client: clientStream2.Write(buffer2, 0, buffer2.Length)
You can get an exception here, or not - depending on whether the server has already closed the connection, in any case the server is not reading anymore.
You need to define your own message protocol that both server and client will honor. For example, you can have the client close the connection when it is done sending:
Client:
using (var client = new TcpClient("localhost", 8888))
using (var clientStream = client.GetStream())
{
var buffer = Encoding.ASCII.GetBytes( File.ReadAllText("FirstNames.txt") );
clientStream.Write(buffer, 0, buffer.Length);
buffer = Encoding.ASCII.GetBytes( File.ReadAllText("LastNames.txt") );
clientStream.Write(buffer, 0, buffer.Length);
}
Server:
using (var tcpClient = (TcpClient)client)
using (var clientStream = tcpClient.GetStream())
{
// Store everything that the client sends.
// This will work if the client closes the connection gracefully
// after sending everything
var receivedData = new MemoryStream();
clientStream.CopyTo(receivedData);
var rawBytes = receivedData.ToArray();
var file = Encoding.ASCII.GetString(rawBytes, 0, rawBytes.Length);
Menu.Insert(theDatabase, file);
}
The protocol is simple, and may be enough for your case. However, there are issues with it which should be addressed in production code (e.g. what if the client sends too much data, exhausting server memory, what if the client stops sending without closing the connection, etc.)
because while (clientStream.DataAvailable) is no longer true after your first client call.
You are exiting your client-recv loop in your server just because DatAvailable is false. This means if the client were to send a frame of data (which you consume) and pause then your server would see no data available at that moment and disconnect, even if a split second later another frame of data from the client was about to come in. Almost always, the end of a dialog is based on the content of the data being passed. You can certainly never try to rely on the fact that DataAvailable happens to be false one time.
As a follow-up, if you provide more info on the protocol that is used we can give more assitance. For example, if the prototcol is that two strings are sent with CR/LF at the end then the server loop should be inspecting the buffer for that to know when to disconnect.