Stopping communication in client server using c# - c#

I am trying to make a client server communication using c# .I have made the client and the server to communicate with each other. But, the problem I am facing is that how do I stop the communication?
Condition: The server should always be listening (when multiple clients are present.) (presently, I am using single client). The client should have a stop or exit condition (ie; when the client sends "exit" the client should terminate, the server should still be listening to other clients) when it finishes transmitting the data.
I am new to c#. Tried searching on google also. but didn't find what I need.
Part of my code:
Server:
try
{
IPAddress addr = IPAddress.Parse("127.0.0.1");
string a = "recieved by server";
TcpListener Receiver = new TcpListener(addr, 1234);
Receiver.Start();
Console.WriteLine("trying to connect to " + addr);
Socket s = Receiver.AcceptSocket();
Console.WriteLine("Connected");
while (true)
{
byte[] b = new byte[100];
int k = s.Receive(b);
char[] chars = new char[b.Length / sizeof(char)];
System.Buffer.BlockCopy(b, 0, chars, 0, b.Length);
string dataReceived = new string(chars);
Console.WriteLine(dataReceived);
byte[] bw = new byte[a.Length * sizeof(char)];
System.Buffer.BlockCopy(a.ToCharArray(), 0, bw, 0, bw.Length);
Console.WriteLine("sending Acknowledgement to client");
s.Send(bw);
}
//Receiver.Stop();
}
Client:
try
{
TcpClient TcpC = new TcpClient();
TcpC.Connect("127.0.0.1", 1234);
while (true)
{
Console.WriteLine("enter somethiong to send");
String s = Console.ReadLine();
NetworkStream CStream = TcpC.GetStream();
byte[] bw = new byte[s.Length * sizeof(char)];
System.Buffer.BlockCopy(s.ToCharArray(), 0, bw, 0, bw.Length);
Console.WriteLine("Transmit");
CStream.Write(bw, 0, bw.Length);
if (s == "exit")
{
CStream.Flush();
CStream.Close();
TcpC.Close();
break;
}
byte[] br = new byte[100];
int k = CStream.Read(br, 0, 100);
char[] chars = new char[br.Length / sizeof(char)];
System.Buffer.BlockCopy(br, 0, chars, 0, br.Length);
string ackReceived = new string(chars);
Console.WriteLine(ackReceived);
}
//TcpC.Close();
}

Once you accepted socket connection from the client using Socket s = Receiver.AcceptSocket(); you need to put your commands processing logic in your while (true) { } block in some another thread (using a Task or Thread whatever), and then you should start accepting new socket connection using Receiver.AcceptSocket(); again.

The problem is you do a
Receiver.Stop();
when it should be the socket you are closing.
The idea is you create a new socket to handle each time a client connects - and that's the connection one you terminate, not the main listening socket.
There is good sample code here:
https://msdn.microsoft.com/en-us/library/system.net.sockets.tcplistener(v=vs.110).aspx

Related

C# Read data sent by server

I'm working on a chatbox app using C# on Visual Studio. I have a console server and a chat with a graphical interface.
I succeed to send data : chatbox -> server. And also server -> chatbox but only for the chatbox that has sent the info (When chatbox has sent an info, the server has to send it to everyone, but it works only for the sender).
I want that all app receive the info.
Actually :
App 1 -> Server
Server -> App 1
Not App 2
I don't understand why. Thanks for your future help.
public void start()
{
TcpListener l = new TcpListener(new IPAddress(new byte[] { 127, 0, 0, 1 }), port);
l.Start();
while(true)
{
TcpClient comm = l.AcceptTcpClient();
Console.WriteLine("Connection established #" + comm);
new Thread(new Receiver(comm).doOperation).Start();
}
}
class Receiver
{
private TcpClient comm;
public Receiver(TcpClient s)
{
comm = s;
}
public void doOperation()
{
Semaphore s = new Semaphore(1, 1);
while (true)
{
s.WaitOne();
NetworkStream nwStream = comm.GetStream();
byte[] buffer = new byte[comm.ReceiveBufferSize];
//---read incoming stream---
int bytesRead = nwStream.Read(buffer, 0, comm.ReceiveBufferSize);
//---convert the data received into a string---
string dataReceived = Encoding.ASCII.GetString(buffer, 0, bytesRead);
Console.WriteLine("Received " + dataReceived);
s.Release();
s.WaitOne();
Console.WriteLine("Send to all : " + dataReceived);
nwStream.Write(buffer, 0, bytesRead);
s.Release();
}
}
}
And I receive the info on the chatbox:
public Form1(string h, int p)
{
...
comm = new TcpClient(h, p);
nwStream = comm.GetStream();
Thread th1 = new Thread(receive);
th1.Start();
}
public void receive()
{
while (true)
{
byte[] bytesToRead = new byte[comm.ReceiveBufferSize];
int bytesRead = nwStream.Read(bytesToRead, 0, comm.ReceiveBufferSize);
MessageBox.Show("Appli info received : " + Encoding.ASCII.GetString(bytesToRead, 0, bytesRead));
}
}
What kind of protocol are you using between [sever <-> client] ?
You need to implement WebSocket protocol on the both side. Server will be able to send events to clients.
After the protocol recognition question, you just need to build / call events to C# back-end side and reveivers javascript side.

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;
}
}

Calling AcceptTcpClient on sockect never continues in a win application

I wrote the code as seen below as a C# console app, and it works correctly.
However when I use in win application it dose not work.
I put in a break point, and it stops on " tcpClient = tcpListener.AcceptTcpClient();" line,
and does not do any work and does not show any thing, and no errors are returned.
part of my code :
void _func_send()
{
byte[] bytes = new byte[512];
IPAddress add = ipHost.AddressList[2];
Socket server = new Socket(add.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
TcpListener tcpListener = null;
tcpListener = new TcpListener(add, 50);
//tcpListener.Stop();
tcpListener.Start();
while (true)
{
/////on this line it stops
tcpClient = tcpListener.AcceptTcpClient();
stream = tcpClient.GetStream();
if (stream.DataAvailable)
{
stream.Read(bytes, 0, bytes.Length);
_txt_show.Text = _txt_show.Text + Encoding.UTF8.GetString(bytes);
byte[] msg = Encoding.UTF8.GetBytes(".:: thanks ::.");
stream.Write(msg, 0, msg.Length);
}
}
}

Java Socket Server and Client Socket c# issue

i have a problem comunicating with a java server socket with my client c# socket.
The problem came from when i try to read the response. My code is this:
IPHostEntry IPHost = Dns.Resolve("IP_ADDRESS");
Console.WriteLine(IPHost.HostName);
string []aliases = IPHost.Aliases;
IPAddress[] addr = IPHost.AddressList;
Console.WriteLine(addr[0]);
EndPoint ep = new IPEndPoint(addr[0],1024);
Socket sock =
new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
sock.Connect(ep);
if(sock.Connected)
Console.WriteLine("OK");
Encoding ASCII = Encoding.ASCII;
string Get = "A";
Byte[] ByteGet = ASCII.GetBytes(Get);
Byte[] RecvBytes = new Byte[256];
sock.Send(ByteGet, ByteGet.Length, 0);
Int32 bytes = sock.Receive(RecvBytes, RecvBytes.Length, 0);
Console.WriteLine(bytes);
String strRetPage = null;
strRetPage = strRetPage + ASCII.GetString(RecvBytes, 0, bytes);
while( bytes > 0 ) {
bytes = sock.Receive(RecvBytes, RecvBytes.Length, 0);
strRetPage = strRetPage + ASCII.GetString(RecvBytes, 0, bytes);
Console.WriteLine(strRetPage );
}
sock.Close();
at the code line
Int32 bytes = sock.Receive(RecvBytes, RecvBytes.Length, 0);
my client hang.
I have to stop the application. It seems that don't respond the socket server.
The specific of the socket server is to send and receive a BitStream.
Without the Java code of your server it's hard to tell, but it seems very likely your server is not sending the expected 256 bytes. Since Socket.Receive is blocking by default the client keeps waiting for data.

TCP Client Server Problem

I have the following code for the server application:
TcpListener recSock = new TcpListener(400);
recSock.Start();
TcpClient client = recSock.AcceptTcpClient();
NetworkStream netStream = client.GetStream();
Byte[] data = new Byte[256];
int i;
while((i = netStream.Read(data, 0, data.Length)) != 0) {
string cmd = ASCIIEncoding.ASCII.GetString(data, 0, i);
Console.WriteLine(cmd);
if(cmd == "R") {
RestartScheduler();
}
}
client.Close();
And the client looks like:
TcpClient client = new TcpClient();
client.Connect("VM-SCHEDULER", 400);
NetworkStream netStream = client.GetStream();
Byte[] data = ASCIIEncoding.ASCII.GetBytes("R");
netStream.Write(data, 0, data.Length);
netStream.Flush();
client.Close();
All is fine the first time the client connects the "R" command is read and the RestartScheduler() method is called, however all subsequent commands fail until the server is restarted.
I have used telnet to connect to the server after the first attempt and it is still listening on the port.
Where am i going wrong?
EDIT:
Basically what I am trying to accomplish is that the server will listen always, a client will then connect send the "R" command then close the connection. The client must be able to connect to the server at any time to issue the command. There will only be 1 client at any given time.
If there is no data to be read, netStream.Read will return 0 and your while loop will exit, disconnecting the client at client.Close();. You have nothing in your code to allow the server to continue receiving in this scenario.
You need to keep listening for connections until the application is shutdown, so put the listen and GetStream in a while loop. Since Stream.Read is a blocking call, you should have some data for the data reading while loop (unless timeout occurs). Otherwise it will close the connection and go back to listening for a new one.
Note: I've not included any error handling in here, you'll need to add that yourself.
TcpListener recSock = new TcpListener(400);
recSock.Start();
while (!stopping)
{
TcpClient client = recSock.AcceptTcpClient();
NetworkStream netStream = client.GetStream();
Byte[] data = new Byte[256];
int i = netStream.Read(data, 0, data.Length);
while(i != 0)
{
string cmd = ASCIIEncoding.ASCII.GetString(data, 0, i);
Console.WriteLine(cmd);
if(cmd == "R") {
RestartScheduler();
}
i = stream.Read(bytes, 0, bytes.Length);
}
client.Close();
Thread.Sleep(1); // Will allow the stopping bool to be updated
}
Module level add:
private bool stopping = false;
In your shutdown function:
stopping = true;
Are you connecting multiple times, or sending multiple commands down the same connection? If you could provide a short but complete program to demonstrate the problem, that would really help.
My guess is that you're running into problems due to reading multiple commands from a single connection in one go, but it's hard to know without more information. Don't forget that a single call to Write from the client can easily result in multiple reads at the server end - or vice versa.
Well the server will exit after the first command it receives, no?
At the least, you're missing using statements:
TcpListener recSock = new TcpListener(IPAddress.Loopback, 400);
recSock.Start();
using (TcpClient client = recSock.AcceptTcpClient())
{
using (NetworkStream netStream = client.GetStream())
{
Byte[] data = new Byte[256];
int i;
while ((i = netStream.Read(data, 0, data.Length)) != 0)
{
string cmd = Encoding.ASCII.GetString(data, 0, i);
Console.WriteLine(cmd);
if (cmd == "R")
{
RestartScheduler();
}
}
}
client.Close();
}
and
using (TcpClient client = new TcpClient())
{
client.Connect("VM-SCHEDULER", 400);
using (NetworkStream netStream = client.GetStream())
{
Byte[] data = Encoding.ASCII.GetBytes("R");
netStream.Write(data, 0, data.Length);
netStream.Flush();
}
client.Close();
}

Categories