Async Call back is not working in BeginReceive - c#

Async Callback in BeginReceive function is not working.
Messages are being received in my port. But my code is not able to receive and process the message.
private void StartListening()
{
try
{
ar_ = udp.BeginReceive(Receive, new object());
}
catch(Exception ex)
{
}
}
private void Receive(IAsyncResult ar)
{
IPEndPoint ip = new IPEndPoint(IPAddress.Any, 7785);
byte[] bytes = udp.EndReceive(ar, ref ip);
string message = Encoding.ASCII.GetString(bytes);
AppendTextBox("Received: " + string.Join("-", bytes) + Environment.NewLine);
}
public void Send(byte[] MsgBytes)
{
try
{
UdpClient client = new UdpClient();
IPEndPoint ip = new IPEndPoint(IPAddress.Parse(txtbx_ip.Text), 7785);
client.Send(MsgBytes, MsgBytes.Length, ip);
client.Close();
AppendTextBox("Sent: " + string.Join("-", MsgBytes) + Environment.NewLine);
StartListening();
}
catch (Exception ex)
{
AppendTextBox("Exception occured: " + ex + Environment.NewLine);
}
}
The Debug point never hits the Receive function after it comes to BeginReceive.
Another information is that, I am using a Static IP in my system. (I am not sure if this is the problem).

Related

C# Winforms using TcpListener I can't connect to server from other devices on my LAN

I have a Winforms application that's going to transfers data to an Android application, for now it accepts a connection and displays a line of text as output. I tested on my local machine using the telnet command in PowerShell and it returns the correct message. When I tried the command from another PC on my network, it just times out and fails to connect. I made sure the port was free and that my firewall was turned off.
Here is my method:
public void senddata()
{
new Thread(() =>
{
Thread.CurrentThread.IsBackground = true;
TcpListener server = null;
try
{
Int32 port = 4296;
IPAddress localAddr =IPAddress.Any;
server = new TcpListener(localAddr, port);
server.Start();
Byte[] bytes = new Byte[256];
while (true)
{
server.Start();
Debug.WriteLine("Waiting for a connection... ");
TcpClient client = server.AcceptTcpClient();
NetworkStream stream = client.GetStream();
Debug.WriteLine("Connected!");
server.Stop();
while (stream.Read(bytes, 0, bytes.Length) != 0)
{
string data = "CPU: " + cpuCircle.Value + " C" + " | GPU: " + gpuCircle.Value + " C";
byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);
stream.Write(msg, 0, msg.Length);
stream.Flush();
}
client.Close();
}
}
catch (SocketException m)
{
Debug.WriteLine("SocketException: "+m);
}
finally
{
server.Stop();
}
}).Start();
}
Any idea what I'm doing wrong?
I think the main issue is that your listener object is being created in Thread itself due to which only first client able to connect. Please make TcpListener object before calling senddata() method and this listener should accept connection before calling senddata() method as well and pass client object to senddata(TcpClient client) method. By doing so you would be able to entertain theoretically unlimited clients simultanously:
Try This:
void StackOverflow4() // Your calling method
{
TcpListener server = null;
Int32 port = 4296;
IPAddress localAddr = IPAddress.Any;
try
{
server = new TcpListener(localAddr, port);
server.Start();
Byte[] bytes = new Byte[256];
while (true)
{
Debug.WriteLine("Waiting for a connection... ");
TcpClient client = server.AcceptTcpClient();
senddata(client);
}
}
catch (SocketException m)
{
Debug.WriteLine("SocketException: " + m);
//Some logic to restart listner
}
catch(Exception ex)
{
Debug.WriteLine(ex.Message);
//Some logic to restart listner
}
}
public void senddata(TcpClient client)
{
new Thread(() =>
{
Thread.CurrentThread.IsBackground = true;
try
{
Byte[] bytes = new Byte[256];
while (true)
{
NetworkStream stream = client.GetStream();
Debug.WriteLine("Connected!");
//server.Stop();
while (stream.Read(bytes, 0, bytes.Length) != 0)
{
string data = "CPU: " + cpuCircle.Value + " C" + " | GPU: " + gpuCircle.Value + " C";
byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);
stream.Write(msg, 0, msg.Length);
stream.Flush();
}
client.Close();
}
}
catch (SocketException m)
{
Debug.WriteLine("SocketException: " + m);
}
finally
{
//server.Stop();
}
}).Start();
}

Send and receive byte[] in server-client TCP application

I need to send and receive bytes in from my client to server over NetworkStream. I know how to communicate with strings, but now I need to send and receive bytes.
For example, something like that:
static byte[] Receive(NetworkStream netstr)
{
try
{
byte[] recv = new Byte[256];
int bytes = netstr.Read(recv, 0, recv.Length); //(**This receives the data using the byte method**)
return recv;
}
catch (Exception ex)
{
Console.WriteLine("Error!\n" + ex.Message + "\n" + ex.StackTrace);
return null;
}
}
static void Send(NetworkStream netstr, byte[] message)
{
try
{
netstr.Write(message, 0, message.Length);
}
catch (Exception ex)
{
Console.WriteLine("Error!\n" + ex.Message + "\n" + ex.StackTrace);
}
}
Server:
private void prejmi_click(object sender, EventArgs e)
{
const string IP = "127.0.0.1";
const ushort PORT = 54321;
TcpListener listener = new TcpListener(IPAddress.Parse(IP), PORT);
listener.Start();
TcpClient client = listener.AcceptTcpClient();
NetworkStream ns = client.GetStream();
byte[] data = Receive(ns)
}
Client:
private void poslji_Click(object sender, EventArgs e)
{
const string IP = "127.0.0.1";
const ushort PORT = 54321;
TcpClient client = new TcpClient();
client.Connect(IP, PORT);
string test="hello";
byte[] mybyte=Encoding.UTF8.GetBytes(test);
Send(ns,mybyte);
}
But that is not the propper way to do this, because byte[] data on server side will always have length of 256.
Thanks, Jon!
static byte[] Receive(NetworkStream netstr)
{
try
{
// Buffer to store the response bytes.
byte[] recv = new Byte[256];
// Read the first batch of the TcpServer response bytes.
int bytes = netstr.Read(recv, 0, recv.Length); //(**This receives the data using the byte method**)
byte[] a = new byte[bytes];
for(int i = 0; i < bytes; i++)
{
a[i] = recv[i];
}
return a;
}
catch (Exception ex)
{
Console.WriteLine("Error!\n" + ex.Message + "\n" + ex.StackTrace);
return null;
}
}
static void Send(NetworkStream netstr, byte[] message)
{
try
{
//byte[] send = Encoding.UTF8.GetBytes(message.ToCharArray(), 0, message.Length);
netstr.Write(message, 0, message.Length);
}
catch (Exception ex)
{
Console.WriteLine("Error!\n" + ex.Message + "\n" + ex.StackTrace);
}
}

Reconnecting to an unclosed Socket connection C#

I have a Listener application which expects a string message for display. I cannot modify this application.
I have to send messages to this listener through my C# client. Both the listener and client are supposed to run on the same PC (local host).
My Code to Connect:
public void ConnectAndSendMessage(string MessageToSend)
{
string localIP = GetIPAddress();
try
{
TcpClient tcpclnt = new TcpClient();
Console.WriteLine("Connecting.....");
tcpclnt.Connect(localIP, 2400);
Socket socket = tcpclnt.Client;
bool connectionStatus = socket.Connected;
if (connectionStatus)
{
//Send Message
ASCIIEncoding asen = new ASCIIEncoding();
//string sDateTime = DateTime.Now.ToString();
int SendStatus = socket.Send(asen.GetBytes(MessageToSend + Environment.NewLine));
}
Thread.Sleep(2000);
tcpclnt.Close();
}
catch (Exception e)
{
Console.WriteLine("Error..... " + e.StackTrace);
}
}
Problem:
The client application runs fine and send the messages successfully to the Listener. But the problem comes if the client gets crashed (I close the client program) before executing tcpclnt.Close();. In this case, if I restart the Client program again then, I cannot connect to the socket since the application didn’t close the socket in the previous run (crashed run).
How can I reconnect to the listener in this condition?
try this one..
public void ConnectAndSendMessage(string MessageToSend)
{
string localIP = GetIPAddress();
using (System.Net.Sockets.TcpClient tcpclnt = new System.Net.Sockets.TcpClient())
{
try
{
Console.WriteLine("Connecting.....");
tcpclnt.Connect(localIP, 2400);
using (System.Net.Sockets.Socket socket = tcpclnt.Client)
{
if (socket.Connected)
{
//Send Message
System.Text.ASCIIEncoding asen = new System.Text.ASCIIEncoding();
//string sDateTime = DateTime.Now.ToString();
int SendStatus = socket.Send(asen.GetBytes(MessageToSend + Environment.NewLine));
}
System.Threading.Thread.Sleep(2000);
}
}
catch (Exception e)
{
Console.WriteLine("Error..... " + e.StackTrace);
}
finally
{
if (tcpclnt != null && tcpclnt.Connected)
tcpclnt.Close();
}
}
}

How to manage the messages from the client to server

I have some clients that connect to the server at the same time, and each of them send to server a registration message.
So, the messages collide with previous messages when they come to the server.
How can I manage the communications without collision between the messages?
I use asynchronous tcp socket in C#.
Here the server:
class ServerSocket
{
//The ClientInfo structure holds the required information about every
//client connected to the server
struct ClientInfo
{
public Socket socket; //Socket of the client
public string strName; //Name by which the user logged into the chat room
}
//The collection of all clients logged into the room (an array of type ClientInfo)
ArrayList clientList;
//The main socket on which the server listens to the clients
Socket serverSocket;
byte[] byteData = new byte[5000];
const int NUM_CLIENT = 12;
public ServerSocket()
{
clientList = new ArrayList();
}
public void LoadServer()
{
try
{
//We are using TCP sockets
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//Assign the any IP of the machine and listen on port number 1000
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, 1000);
//Bind and listen on the given address
serverSocket.Bind(ipEndPoint);
serverSocket.Listen(NUM_CLIENT);
//Accept the incoming clients
serverSocket.BeginAccept(new AsyncCallback(OnAccept), null);
Console.WriteLine("###################### S E R V E R ######################");
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private void OnAccept(IAsyncResult ar)
{
try
{
Socket clientSocket = serverSocket.EndAccept(ar);
//Start listening for more clients
serverSocket.BeginAccept(new AsyncCallback(OnAccept), null);
//Once the client connects then start receiving the commands from her
clientSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None, new AsyncCallback(OnReceive), clientSocket);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private void OnReceive(IAsyncResult ar)
{
string msgReceived = "";
try
{
Socket clientSocket = (Socket)ar.AsyncState;
clientSocket.EndReceive(ar);
msgReceived = GetString(byteData);
string strTemp = "";
for (int i = 0; i < msgReceived.IndexOf("<END>"); i++)
{
strTemp += msgReceived[i];
}
msgReceived = strTemp;
XmlBaseClientMsg xmlBaseClientMsg = new XmlBaseClientMsg();
BaseClientMsg baseClientMsgReceived = new BaseClientMsg();
baseClientMsgReceived = xmlBaseClientMsg.DeserializeFromString(msgReceived);
switch (baseClientMsgReceived.m_messageType)
{
case ClientMsgType.AI_REGISTRATION:
//When a user logs in to the server then we add him to our list of clients
ClientInfo AIClientInfo = new ClientInfo();
AIClientInfo.socket = clientSocket; // save the socket
AIClientInfo.strName = baseClientMsgReceived.m_sSenderID; // save the name of sender client
clientList.Add(AIClientInfo);
Console.WriteLine("The client: " + AIClientInfo.strName + " registered");
break;
case ClientMsgType.ENTITY_REGISTRATION:
//When a user logs in to the server then we add him to our list of clients
ClientInfo EntityClientInfo = new ClientInfo();
EntityClientInfo.socket = clientSocket; // save the socket
EntityClientInfo.strName = baseClientMsgReceived.m_sSenderID; // save the name of sender client
clientList.Add(EntityClientInfo);
Console.WriteLine("The client: " + EntityClientInfo.strName + " registered");
break;
#region
//case Command.Logout:
// //When a user wants to log out of the server then we search for her
// //in the list of clients and close the corresponding connection
// int nIndex = 0;
// foreach (ClientInfo client in clientList)
// {
// if (client.socket == clientSocket)
// {
// clientList.RemoveAt(nIndex);
// break;
// }
// ++nIndex;
// }
// clientSocket.Close();
// break;
#endregion
}
if (baseClientMsgReceived.m_messageType != ClientMsgType.AI_REGISTRATION)
{
Console.WriteLine("Type message: " + baseClientMsgReceived.m_messageType + " To: " +
baseClientMsgReceived.m_sReceiverID + " From: " + baseClientMsgReceived.m_sSenderID);
foreach (ClientInfo clientInfo in clientList)
{
if (clientInfo.strName == baseClientMsgReceived.m_sReceiverID)
{
byte[] message;
message = GetBytes(msgReceived);
// Send the message to reciever client
clientInfo.socket.BeginSend(message, 0, message.Length, SocketFlags.None,
new AsyncCallback(OnSend), clientInfo.socket);
Console.WriteLine("Msg No : " + baseClientMsgReceived.m_nMessageID + " Type: " + baseClientMsgReceived.m_messageType + " ==> has been sent");
break;
}
}
}
////If the user disconnects so no need to listen to him
// if (baseClientMsgReceived.m_messageType != ClientMsgType.Logout)
//{
//Start listening to the message send by the user
clientSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None, new AsyncCallback(OnReceive), clientSocket);
//}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public void OnSend(IAsyncResult ar)
{
try
{
Socket client = (Socket)ar.AsyncState;
client.EndSend(ar);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
static string GetString(byte[] bytes)
{
char[] chars = new char[bytes.Length / sizeof(char)];
System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
return new string(chars);
}
}
class Program
{
public static int Main( String[] args )
{
ServerSocket serverSocket = new ServerSocket();
serverSocket.LoadServer();
while(true)
{
Console.ReadLine();
}
}
}
}

Server socket in Android, Client sockect C# not sending until socket close

I have a socket server in Android and a client Socket in C#. The socket stablish connection properly but the information is not sended until the socket is close. Ot seems that the information is in buffer and it is not sended until the resources must be released.
The server code is:
Socket socket = null;
DataInputStream dataInputStream = null;
DataOutputStream dataOutputStream = null;
try {
serverSocket = new ServerSocket(SocketServerPORT);
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
info.setText("I'm waiting here: "+ serverSocket.getLocalPort());
}
});
while (true) {
socket = serverSocket.accept();
dataInputStream = new DataInputStream(socket.getInputStream());
dataOutputStream = new DataOutputStream(socket.getOutputStream());
String messageFromClient = "";
//If no message sent from client, this code will block the program
messageFromClient = dataInputStream.readLine();
count++;
message += "#" + count + " from " + socket.getInetAddress()+ ":" + socket.getPort() + "\n" + "Msg from client: " + messageFromClient + "\n";
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
msg.setText(message);
}
});
And the client code is:
IPAddress host = IPAddress.Parse("192.168.1.129");
IPEndPoint hostep = new IPEndPoint(host, 8080);
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
sock.Connect(hostep);
//sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoDelay, true);
}
catch (SocketException ex) {
Console.WriteLine("Problem connecting to host");
Console.WriteLine(e.ToString());
sock.Close();
return;
}
try
{
string theMessageToSend = "Que mierda es esta";
byte[] msg = Encoding.Unicode.GetBytes(theMessageToSend + "$");
sock.Send(msg);
//sock.Send(Encoding.ASCII.GetBytes("testing %"));
} catch (SocketException ex) {
Console.WriteLine("Problem sending data");
Console.WriteLine( e.ToString());
sock.Close();
return;
}
sock.Close();
I can not reach the line messageFromClient = dataInputStream.readLine(); in the server side until the sock.Close(); is executed in the client side.
Many thanks in advance!

Categories