Calling AcceptTcpClient on sockect never continues in a win application - c#

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

Related

Keep TcpListerner in Idle state C#

i have these code for a server and client program. client program sends a value to server and server reads it. but here after first message, server shuts down.
i want it to be listerning until the full application shuts down. so after 1 connection closes, it will wait for next connection and so on.
internal static async Task ServerHandler()
{
Console.Writeline("starting server...");
IPAddress b = IPAddress.Any;
TcpListener Server = new TcpListener(b, 5550);
Server.Start();
Console.Writeline("Server Started Sucessfully!");
Console.Writeline("Waiting for Connection...");
TcpClient Client = Server.AcceptTcpClient();
string clientIPAddress = "Connected! => " + IPAddress.Parse(((IPEndPoint)Client.Client.RemoteEndPoint).Address.ToString());
Console.Writeline(clientIPAddress);
byte[] message = new byte[4096];
int bytesRead;
while (true)
{
try
{
Stream MessageStream = Client.GetStream();
bytesRead = MessageStream.Read(message, 0, 4096);
ASCIIEncoding encoder = new ASCIIEncoding();
string recivedMessage = encoder.GetString(message, 0, bytesRead);
Console.Writeline(recivedMessage);
}
catch (Exception e)
{
Console.WriteLine(e);
}
Client.Close();
Server.Stop();
}
}

Stopping communication in client server using 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

Acknowledgement didn't work..Teltonika FM5300

Here is a sample of my code. It doesn't work. I sent acknowledgement in the right form {0x01} but the device always returns only IMEI. Could someone solve this problem?
static void Main(string[] args)
{
TcpListener list = new TcpListener(new IPEndPoint(IPAddress.Any, 2065));
TcpClient client;
Console.WriteLine("Listening... \n");
list.Start(1);
list.Server.NoDelay = true;
while (true)
{
Console.WriteLine("Waiting for client...\n");
client = list.AcceptTcpClient();
Console.WriteLine("Client connected ");
byte[] imei = new byte[8192];
NetworkStream ns = client.GetStream();
if (ns.CanRead)
{
ns.Read(imei, 0, (int)client.ReceiveBufferSize);
}
Console.WriteLine(Encoding.ASCII.GetString(imei, 0, imei.Length));
byte[] ack = new byte[1] {0x01};
if (ns.CanWrite)
{
ns.Write(ack, 0, ack.Length);
}
client.Close();
}
}
Like Ron said, you keep sending the same thing over and over. After you receive IMEI, your code sends correct response and disconnects. So next connection starts from beginning, with IMEI... The data from device comes over the same connection, so... why disconnect? ;)
– mlask

Reading data from a TCP Socket not getting all of the data

I am working on a C# and android client/server application.
Android is sending a message to C# and I can see it is sending the correct data, however C# doesn't receive all of it.
Below is the code I have in C#
TcpListener tcpListener = new TcpListener(IPAddress.Any, serverTCPPort);
tcpListener.Start();
while (true)
{
tcpClient = tcpListener.AcceptTcpClient();
stream = tcpClient.GetStream();
reader = new StreamReader(stream);
writer = new StreamWriter(stream);
writer.NewLine = "\r\n";
writer.AutoFlush = true;
byte[] serverData = new byte[tcpClient.ReceiveBufferSize];
int length = stream.Read(serverData, 0, serverData.Length);
string received = Encoding.ASCII.GetString(serverData, 0, length);
}
Below is how I am sending the data via Android
i
f (contactInformation.photoBase64String != null) {
bitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(), Uri.parse(contactInformation.photoBase64String));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] b = baos.toByteArray();
bitmap64Encoded = Base64.encodeToString(b, Base64.DEFAULT);
}
Toast.makeText(context, "Incoming call from " + contactInformation.contactName, Toast.LENGTH_LONG).show();
XmlSettings xmlSettings = new XmlSettings();
xmlSettings.setIndent(true);
XmlWriter xmlWriter = new XmlWriter(xmlSettings);
xmlWriter.writeStartDocument();
xmlWriter.writeStartElement("StatusManager");
xmlWriter.writeElementString("Command", Defines.ServerCommands.IncomingCall.toString());
xmlWriter.writeStartElement("CallInformation");
xmlWriter.writeElementString("PhoneNumber", phoneNumber);
xmlWriter.writeElementString("ContactName", contactInformation.contactName);
if (contactInformation.photoBase64String != null)
{
xmlWriter.writeElementString("PhotoUri", bitmap64Encoded);
}
xmlWriter.writeEndElement();
xmlWriter.writeEndElement();
String xml = xmlWriter.returnXmlOutput();
TCPSender tcpSender = new TCPSender(context, DeviceManagement.servers.get(0), xmlWriter.returnXmlOutput());
Thread thread = new Thread(tcpSender);
thread.start();
The TCP Sender is
#Override
public void run() {
Log.d("TCPSender", xml);
HelperClass helperClass = new HelperClass();
try
{
Socket socket = new Socket(foundServerInformation.ipAddress, foundServerInformation.tcpServerPort);
OutputStream out = socket.getOutputStream();
PrintWriter output = new PrintWriter(out);
output.println(xml);
output.flush();
I guess the data is too big for the byte array but I can't find a way of how to ensure I get all of the information that Android is sending.
It's difficult to know where the problem might be (I see your code is OK), but here you have a working example from Microsoft how it should be done, maybe it gives you some clues.
TcpListener server=null;
try
{
// Set the TcpListener on port 13000.
Int32 port = 13000;
IPAddress localAddr = IPAddress.Parse("127.0.0.1");
// TcpListener server = new TcpListener(port);
server = new TcpListener(localAddr, port);
// Start listening for client requests.
server.Start();
// 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!");
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();
}
Console.WriteLine("\nHit enter to continue...");
Console.Read();
I've finally managed to get it working, it was something to do with using the SendReceiveBuffer which I did try but didn't work but now it does so I guess I missed something.
Below is the code I am using to receive all of the data
TcpListener tcpListener = new TcpListener(IPAddress.Any, serverTCPPort);
tcpListener.Start();
string received = "";
while (true)
{
tcpClient = tcpListener.AcceptTcpClient();
stream = tcpClient.GetStream();
reader = new StreamReader(stream);
writer = new StreamWriter(stream);
writer.NewLine = "\r\n";
writer.AutoFlush = true;
byte[] bytes = new byte[tcpClient.SendBufferSize];
int recv = 0;
while (true)
{
recv = stream.Read(bytes, 0, tcpClient.SendBufferSize);
received += System.Text.Encoding.ASCII.GetString(bytes, 0, recv);
if (received.EndsWith("\n\n"))
{
break;
}
}
}

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