I am trying to create a async socket server but it does not wait for a client to connect and exits
class Program
{
IPAddress ipadd;
int port;
TcpListener tcplistener;
public async void startListeningForConnection(IPAddress ip = null, int dport = 23000)
{
if (ip == null)
{
ip = IPAddress.Any;
}
if (dport <= 0)
{
dport = 23000;
}
ipadd = ip;
port = dport;
tcplistener = new TcpListener(ipadd, port);
try
{
tcplistener.Start();
Console.WriteLine("Ready to accept client request.");
while (true)
{
TcpClient clientResponse =await tcplistener.AcceptTcpClientAsync();
HandleClientRequest(clientResponse);//method displays the message from client
}
}
catch (Exception ex)
{
Console.WriteLine("Exception occured: {0}", ex.ToString());
}
}
private void HandleClientRequest(TcpClient acceptReturn)
{
NetworkStream stream = null;
StreamReader reader = null;
try
{
stream = acceptReturn.GetStream();
reader = new StreamReader(stream);
char[] buff = new char[64];
Console.WriteLine("***Ready to read");
while (true)
{
int nRet = reader.Read(buff, 0, buff.Length);
if (nRet == 0)
{
Console.WriteLine("Socket disconnected");
break;
}
string receivedText = new string(buff);
Console.Write(receivedText);
Array.Clear(buff, 0, buff.Length);
stream.Flush();
}
stream.Close();
}
catch (Exception ex)
{
Console.WriteLine("Unknown Exception: {0}", ex.ToString());
}
finally
{
tcplistener.Stop();
Console.WriteLine("Exiting");
}
}
When i run startListeningForConnection(), I get this:
Output:
Ready to accept client request.
Press any key to continue . . .
it does not wait for a client to connect. If I remove the async and await then the program works as intended. Can anyone help me as it is my first socket program.
Related
I need to develop a software that catch all alarm alerts from a Sur-Gard System 1.
For now I created this tcp listener en c# and works fine using my phone as a client but it does not stablish communication with the Sur-Gard, I pingued to the sur-gard IP and there is communication between them, and I'm sure that the port it's correct.
What I'm doing wrong?
static void Main(string[] args)
{
Reconect:
System.Net.Sockets.TcpListener server = null;
try
{
Int32 port = 1025;
server = new System.Net.Sockets.TcpListener(IPAddress.Any, port);
server.Start();
while (true)
{
Console.WriteLine($#"Waiting for a connection... ");
TcpClient client = server.AcceptTcpClient();
ThreadPool.QueueUserWorkItem(ThreadProc, client);
}
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
finally
{
server.Stop();
}
goto Reconect;
}
private static void ThreadProc(object obj)
{
var client = (TcpClient)obj;
Console.WriteLine("Connected!");
Byte[] bytes = new Byte[1024];
String cadena_obtenida = null;
cadena_obtenida = null;
NetworkStream stream = client.GetStream();
int i;
try
{
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
cadena_obtenida = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine("Alerta recibida: {0}", cadena_obtenida);
byte[] respuesta = System.Text.Encoding.ASCII.GetBytes("El servidor ha recibido: " + cadena_obtenida + Environment.NewLine);
stream.Write(respuesta, 0, respuesta.Length);
stream.Flush();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
client.Close();
}
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();
}
}
}
}
I have async tcp server that can accept multiple clients at the same time. The scenarios where client requests data from server are served well. Now I am trying to implement the situation in which server has to find a particular client and send some data to it i.e. the client is connected but has not requested data but server wants to send some data to it. How can I find the thread that is already running between the server and client and place data on it?
Here is server code:
public async void RunServerAsync()
{
tcpListener.Start();
while (true)
{
try
{
var client = await tcpListener.AcceptTcpClientAsync();
Accept(client);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
private async void Accept(TcpClient client)
{
//get client information
String clientEndPoint = client.Client.RemoteEndPoint.ToString();
Console.WriteLine("Client connected at " + clientEndPoint );
await Task.Yield ();
try
{
using (client)
using (NetworkStream stream = client.GetStream())
{
byte[] dataReceived = new byte[100];
while (true) //read input stream
{
try
{
int x = await stream.ReadAsync(dataReceived, 0, dataReceived.Length);
if (x != 0)
{
//pass on data for processing
byte[] dataToSend = await ProcessData(dataReceived);
//send response,if any, to the client
if (dataToSend != null)
{
await stream.WriteAsync(dataToSend, 0, dataToSend.Length);
ConsoleMessages.DisplayDataSent(dataReceived, dataToSend);
}
}
}
catch (ObjectDisposedException)
{
stream.Close();
}
}
}
} //end try
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}//end Accept(TcpClient client)
You need to keep track of your clients. For example:
ConcurrentDictionary<Guid, TcpClient> _clients = new ConcurrentDictionary<Guid, TcpClient>();
public async void RunServerAsync()
{
tcpListener.Start();
while (true)
{
try
{
var client = await tcpListener.AcceptTcpClientAsync();
var clientId = Guid.NewGuid();
Accept(clientId, client);
_clients.TryAdd(clientId, client);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
public Task SendAsync(Guid clientId, Byte[] buffer, Int32 offset, Int32 count)
{
TcpClient client;
if (_clients.TryGetValue(clientId, out client))
return client.GetStream().WriteAsync(buffer, offset, count);
// client disconnected, throw exception or just ignore
return Task.FromResult<Object>(null);
}
public Boolean TryGetClient(Guid clientId, out TcpClient client)
{
return _clients.TryGetValue(clientId, out client);
}
private async void Accept(Guid clientId, TcpClient client)
{
//get client information
String clientEndPoint = client.Client.RemoteEndPoint.ToString();
Console.WriteLine("Client connected at " + clientEndPoint);
await Task.Yield();
try
{
using (client)
using (NetworkStream stream = client.GetStream())
{
byte[] dataReceived = new byte[100];
while (true) //read input stream
{
try
{
int x = await stream.ReadAsync(dataReceived, 0, dataReceived.Length);
if (x != 0)
{
//pass on data for processing
byte[] dataToSend = await ProcessData(dataReceived);
//send response,if any, to the client
if (dataToSend != null)
{
await stream.WriteAsync(dataToSend, 0, dataToSend.Length);
ConsoleMessages.DisplayDataSent(dataReceived, dataToSend);
}
}
}
catch (ObjectDisposedException)
{
stream.Close();
}
}
}
} //end try
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
// deregister client
_clients.TryRemove(clientId, out client);
}
}//end Accept(TcpClient client)
TCP is bi-directional, so either side can send data whenever they want.
What you need to do is store a reference to the TcpClient on Accept, something like:
//Class Level
List<TcpClient> connectedClients = List<TcpClient>();
private async void Accept(TcpClient client)
{
connectedClients.Add(client);
...
}
public SendMessage(int index, String message)
{
//pseudo-code
connectedClients[index].Send(message);
}
Normally I will raise an event on connect so whoever is using the class can get the new client's index. The send message code is pseudo-code, there are good examples on MSDN of how to actually perform the send.
I'm trying to create this simple client-server. I have an android client and c#server. just a simple program that sends a hello message to the server but the message isn't sent.
my java code:
Thread t= new Thread()
{
#Override
public void run() {
// TODO Auto-generated method stub
try {
Socket myClient= new Socket("192.167.01.123",7000);
DataOutputStream dos= new DataOutputStream(myClient.getOutputStream());
dos.writeBytes("Hello");
dos.flush();
dos.close();
myClient.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
System.out.println("unknown host");
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("IOExxception");
}
}
};
t.start();
Toast.makeText(this," Message sent" , Toast.LENGTH_SHORT).show();
}
and c# code:
static void Main(string[] args)
{
TcpListener serverSocket = new TcpListener(7000);
TcpClient clientSocket = new TcpClient();
serverSocket.Start();
Console.WriteLine("Server started.");
clientSocket = serverSocket.AcceptTcpClient();
Console.WriteLine("Accept conns from client.");
while (true)
{
try
{
NetworkStream networkStream = clientSocket.GetStream();
Byte[] bytes = new Byte[10025];
networkStream.Read(bytes, 0, (int)clientSocket.ReceiveBufferSize);
string dataClient = System.Text.Encoding.ASCII.GetString(bytes);
Console.WriteLine("data from client: " + dataClient);
networkStream.Flush();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
clientSocket.Close();
serverSocket.Stop();
Console.WriteLine("EXIT");
Console.ReadKey();
}
}
}
Should be inside the while loop
clientSocket = serverSocket.AcceptTcpClient();
Try this:
c# Server Class to Receive Message :
class Server
{
int BUFSIZE = 100;
int servPort = 1551;
public static String ClientOrder = "";
public static int bytesRcvd;
public void RunServer()
{
TcpListener listener = null;
TcpClient client = null;
NetworkStream netStream = null;
listener = new TcpListener(IPAddress.Any, servPort);
listener.Start();
byte[] rcvBuffer = new byte[BUFSIZE];
while (true)
{
client = listener.AcceptTcpClient(); // Get clien
netStream = client.GetStream();
{
rcvBuffer = new byte[BUFSIZE];
bytesRcvd = netStream.Read(rcvBuffer, 0, rcvBuffer.Length);
ClientOrder = (Encoding.ASCII.GetString(rcvBuffer)).Substring(0, bytesRcvd);
netStream.Close();
client.Close();
}
}
}
}
Android Client Class to Send Message:
public class Send_Message_To_Server implements Runnable {
private String mMsg,Server;
private Socket client;
private PrintWriter printwriter;
public Send_Order_To_Server(String msg,String IP) {
mMsg = msg;
Server=IP;
}
public void run() {
try {
client = new Socket(Server, 1551); //connect to server
printwriter = new PrintWriter(client.getOutputStream(),true);
printwriter.write(mMsg); //write the message to output stream
printwriter.flush();
printwriter.close();
client.close(); //closing the connection
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
i'm trying to write simple tcp\ip client-server.
here is server code:
internal class Program
{
private const int _localPort = 7777;
private static void Main(string[] args)
{
TcpListener Listener;
Socket ClientSock;
string data;
byte[] cldata = new byte[1024];
Listener = new TcpListener(_localPort);
Listener.Start();
Console.WriteLine("Waiting connections [" + Convert.ToString(_localPort) + "]...");
try
{
ClientSock = Listener.AcceptSocket();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return;
}
int i = 0;
if (ClientSock.Connected)
{
while (true)
{
try
{
i = ClientSock.Receive(cldata);
}
catch
{
}
try
{
if (i > 0)
{
data = Encoding.ASCII.GetString(cldata).Trim();
ClientSock.Send(cldata);
}
}
catch
{
ClientSock.Close();
Listener.Stop();
Console.WriteLine(
"Server closing. Reason: client offline. Type EXIT to quit the application.");
}
}
}
}
}
And here is client code:
void Main()
{
string data; // Юзерская дата
byte[] remdata ={ };
TcpClient Client = new TcpClient();
string ip = "127.0.0.1";
int port = 7777;
Console.WriteLine("\r\nConnecting to server...");
try
{
Client.Connect(ip, port);
}
catch
{
Console.WriteLine("Cannot connect to remote host!");
return;
}
Console.Write("done\r\nTo end, type 'END'");
Socket Sock = Client.Client;
while (true)
{
Console.Write("\r\n>");
data = Console.ReadLine();
if (data == "END")
break;
Sock.Send(Encoding.ASCII.GetBytes(data));
Sock.Receive(remdata);
Console.Write("\r\n<" + Encoding.ASCII.GetString(remdata));
}
Sock.Close();
Client.Close();
}
When i'm sending to my server i cannt receive data back answer. Sock.Receive(remdata) returns nothing! Why?
You're trying to receive to an empty buffer. You should allocate the buffer with a sensible size, and then take note of the amount of data received:
byte[] buffer = new byte[1024];
...
int bytesReceived = socket.Receive(buffer);
string text = Encoding.ASCII.GetString(buffer, 0, bytesReceived);
(It's somewhat unconventional to use PascalCase for local variables, by the way. I'd also urge you not to just catch Exception blindly, and not to swallow exceptions without logging them.)