Can i recevied a int on StreamReader Sockets C#?
I am developed a app client in java data send a int by sockets to app server in C# but i don't know how can i recevied a int. Because if i put a int mensagem = sr.ReadLine() not work !
The code of server app in C#:
//Some code not include.
public void Server()
{
Socket soc = listener.AcceptSocket();
//Informa uma conecção
//MessageBox.Show("Conectado: " + soc.RemoteEndPoint);
try
{
Stream s = new NetworkStream(soc);
StreamReader sr = new StreamReader(s);
StreamWriter sw = new StreamWriter(s);
sw.AutoFlush = true; // enable automatic flushing
while (true)
{
string mensagem = sr.ReadLine(); //if i put int message not work why?
comando(mensagem);
}
//s.Close();
}
catch (Exception e)
{
MessageBox.Show("Erro!" + e.Message);
}
//MessageBox.Show("Disconectado: " + soc.RemoteEndPoint);
//soc.Close();
} //Fim Função Server
ReadLine returns a string. You can use TryParse to get your integer:
int fromClient;
if (!int.TryParse(mensagem, out fromClient))
{
// error parsing as integer
}
// fromClient is either the parsed value or 0 if TryParse was false
Related
I have inherited the code below, from another developer, which makes requests to an external system.
I call the GenerateRequest method using different values for the 'method' parameter (from a BackgroundWorker) all of which work fine. When I then make a second call it still works for all but one of the 'method' values (which also contains different values for the 'parameters' value, I'll include the calls too below), which hangs on the StreamReader ReadLine() call. However, if I debug and step through the code allowing 10-20 seconds, the output shows a few 'The thread 0xd0f0 has exited with code 0 (0x0)' messages and the code then works.
I feel I have an issue with the thread from which I'm doing this work, but I can't figure it out, please help.
This works everytime;
ClientParameters parameters = new ClientParameters();
string request = requestHandler.GenerateRequest("GetFunctions", parameters);
This only works the first time, unless I debug and step through, allowing time for threads to exit.
ClientParameters parameters = new ClientParameters();
parameters.Filter = new ClientParametersFilter();
parameters.Filter.Demographics = "";
parameters.Filter.Medication = "";
parameters.Filter.MinEffectiveDate = DateTime.Now;
parameters.Filter.MaxEffectiveDate = DateTime.MaxValue;
string request = null;
try
{
request = requestHandler.GenerateRequest("GetRecord", parameters);
}
catch(Exception e)
{
// log error
return null;
}
Hear is the class for making requests;
public class MyRequestHandler : IRequestHandler{
public string GenerateRequest(string method, ClientParameters parameters)
{
ClientIntegrationRequest request = new ClientIntegrationRequest();
request.APIKey = ApplicationSettings.APIKey;
request.Function = method;
request.FunctionVersion = 1.0M;
request.RequestUID = DateTime.Now.ToString();
request.DeviceID = ApplicationSettings.DeviceId;
request.DeviceVersion = ApplicationSettings.DeviceVersion;
request.FunctionParameters = parameters;
XmlSerializer ser = new XmlSerializer(typeof(ClientIntegrationRequest));
string xml;
using (MemoryStream m = new MemoryStream())
{
ser.Serialize(m, request);
// reset to 0
m.Position = 0;
xml = new StreamReader(m).ReadToEnd();
}
try
{
TcpClient tcpClient = new TcpClient("127.0.0.1", ApplicationSettings.Port);
NetworkStream netStream = tcpClient.GetStream();
if (netStream.CanWrite)
{
xml = xml + "\n";
Byte[] sendBytes = Encoding.UTF8.GetBytes(xml);
netStream.Write(sendBytes, 0, sendBytes.Length);
netStream.Flush();
}
else
{
tcpClient.Close();
netStream.Close();
return null;
}
netStream = tcpClient.GetStream();
if (netStream.CanRead)
{
StreamReader l_textReader = new StreamReader(netStream);
string str = l_textReader.ReadLine(); // Here's the issue
l_textReader.Close();
tcpClient.Close();
netStream.Close();
return str.ToString();
}
else
{
tcpClient.Close();
netStream.Close();
return null;
}
}
catch (SocketException e)
{
// log error
return null;
}
catch (Exception e)
{
// log error
return null;
}
}}
If you look the Microsoft example: https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.tcpclient.getstream?view=netframework-4.7.2
you can view that the code read the client stream by low level code reading the content returned by a byte array:
if (netStream.CanRead)
{
// Reads NetworkStream into a byte buffer.
byte[] bytes = new byte[tcpClient.ReceiveBufferSize];
// Read can return anything from 0 to numBytesToRead.
// This method blocks until at least one byte is read.
netStream.Read (bytes, 0, (int)tcpClient.ReceiveBufferSize);
// Returns the data received from the host to the console.
string returndata = Encoding.UTF8.GetString (bytes);
Console.WriteLine ("This is what the host returned to you: " + returndata);
}
Can you try this reading method?
I have a TCP server which writes data back to the client only for certain messages which the clients sends to the server.
It is basically is a command based server for which the server responds with a string only for certain commands otherwise nothing is sent back to the client.
The code given below is an approach which assumes that if any data is sent by the server it shows it as "MESSAGE FROM SERVER" appended with the data which was sent.
class TcpEchoClient
{
static void Main(string[] args)
{
Console.WriteLine("Starting echo client...");
string ipaddress = "127.0.0.1";
TcpClient client = null;
NetworkStream netstream = null;
try
{
client = new TcpClient(ipaddress,1000);
netstream = client.GetStream();
}
catch
{
Console.ReadKey();
Environment.Exit(0);
}
while(true)
{
Console.WriteLine("Message : ");
string t = Console.ReadLine();
string readdata = null;
Console.WriteLine("\n");
if (write(t,netstream))
{
Console.WriteLine("Message sent.");
if (client.Available!=0)
{
readdata = read(netstream);
Console.WriteLine("MESSAGE FROM SERVER : "+readdata);
}
}
else
{
Console.WriteLine("Unable to send message.");
}
}
}
static bool write(string dat, NetworkStream stream)
{
try
{
StreamWriter writer = new StreamWriter(stream) { AutoFlush = true };
try{writer.WriteLine(dat);}
catch (IOException){return false;}
if (SHAHash(dat, "DATA") != SHAHash(read(stream), "DATA"))
return false;
}catch (InvalidOperationException){return false;}
return true;
}
static string read(NetworkStream stream)
{
StreamReader reader = new StreamReader(stream);
string readdata = null;
try
{
readdata = reader.ReadLine();
reader.BaseStream.Flush();
}
catch(IOException)
{
return null;
}
return readdata;
}
}
The function SHAHash is not shown in this post. Its format is SHAHash(message,salt).
The problem faced is that messages sent by the server is not always read by the client. Sometimes the data sent by the server shows up a the client console, and sometimes it does not.
What correction should I make to the above code so that I can read data from the server only when it sends it. That is I require the following code to be executed only when the server sends some data to the client otherwise it should not be executed.
readdata = read(netstream);
Console.WriteLine("MESSAGE FROM SERVER : "+readdata);
Be prudent when using flush or autoflush. Sometimes it executes before send/receive operations... but this usually happens when working with threads.
My first tip that the stream readers/writers are not destructed properly. Try packing them into a using statement.
TCP isnt synchronous so you can't write data and expect the response to be available immediately. When you do the following check
if (client.Available!=0)
there is no guarantee that the server has sent any response yet. You need to keep checking until there is data available or read the data asynchronously
I would use NetworkStream.BeginRead and callbacks to get the server response
class StreamData
{
public NetworkStream netstream;
public byte[] myReadBuffer;
}
class TcpEchoClient
{
static void Main(string[] args)
{
Console.WriteLine("Starting echo client...");
string ipaddress = "127.0.0.1";
TcpClient client = null;
NetworkStream netstream = null;
try
{
client = new TcpClient(ipaddress, 13000);
netstream = client.GetStream();
}
catch
{
Console.ReadKey();
Environment.Exit(0);
}
var streamData = new StreamData
{
netstream = netstream,
myReadBuffer = new byte[1024],
};
netstream.BeginRead(streamData.myReadBuffer, 0, streamData.myReadBuffer.Length,
new AsyncCallback(myReadCallBack),
streamData);
while (true)
{
Console.WriteLine("Message : ");
string t = Console.ReadLine();
Console.WriteLine("\n");
if (write(t, netstream))
{
Console.WriteLine("Message sent.");
}
else
{
Console.WriteLine("Unable to send message.");
}
}
}
static void myReadCallBack(IAsyncResult ar)
{
var streamData = (StreamData)ar.AsyncState;
int bytesRead = streamData.netstream.EndRead(ar);
var readdata = Encoding.ASCII.GetString(streamData.myReadBuffer, 0, bytesRead);
//Be aware that this might not be the complete message depending on the size of the message and the buffer size
Console.WriteLine("You received the following message : " + readdata);
//Start waiting for more data
streamData.netstream.BeginRead(streamData.myReadBuffer, 0, streamData.myReadBuffer.Length,
new AsyncCallback(myReadCallBack),
streamData);
}
static bool write(string dat, NetworkStream stream)
{
try
{
StreamWriter writer = new StreamWriter(stream) { AutoFlush = true };
try { writer.WriteLine(dat); }
catch (IOException) { return false; }
//if (SHAHash(dat, "DATA") != SHAHash(read(stream), "DATA"))
// return false;
}
catch (InvalidOperationException) { return false; }
return true;
}
}
I'm making a server - client program using TcpClient and server.
To send from the server I use:
static void send(string data)
{
sw.WriteLine(data + Environment.NewLine);
}
And when the client connects I'm sending some text:
client = listener.AcceptTcpClient();
sr = new StreamReader(client.GetStream());
sw = new StreamWriter(client.GetStream());
string line;
try
{
send("Hello world");
} //More code
And to read from client:
string data;
data = sr.ReadLine();
if(data != string.Empty || data != null)
{
MessageBox.Show(data);
}
I tried putting inside while(true) and it froze, I tried putting inside a timer tick loop and it froze...
How do I fix this?
P.S: The client and the server are 2 different projects.
I believe you need something like this:
try
{
listen = new TcpListener(myAddress, port);
listen.Start();
Byte[] bytes;
while (true)
{
TcpClient client = listen.AcceptTcpClient();
NetworkStream ns = client.GetStream();
if(client.ReceiveBufferSize > 0){
bytes = new byte[client.ReceiveBufferSize];
ns.Read(bytes, 0, client.ReceiveBufferSize);
string msg = Encoding.ASCII.GetString(bytes); //the message incoming
MessageBox.Show(msg);
}
}
}
catch(Exception e)
{
//e
}
Then have this code as a background thread:
Thread thread = new Thread(the functions name);
thread.IsBackground = true;
thread.Start();
I hope I understand what you need.
Try this one, grandpa's way.
int i = 0;
while (stream.DataAvailable == true)
{
bytes[i] = ((byte)stream.ReadByte());
i++;
}
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine("Received: {0}", data);
This is a program to search for strings from a file. The string required by the client is given from the client side, in my case, using telnet. The program I have written is a server side one. It accepts multiple clients.
But, the problems I am unable rectify are-
It doesn't check for strings from the file.
As soon as the client gets connected, the client cannot type in the strings they want to search in that particular file.
It doesn't send the reply back (i.e. If the string is present in the file or not) to the client. Its only shown on the server side.
How do I proceed further? Could someone tell me where am I going wrong? Could someone please help me out with the code?
This is my try at the program..
class Program
{
static void Main(string[] args)
{
IPAddress ipad = IPAddress.Parse("192.168.0.181");
TcpListener serversocket = new TcpListener(ipad, 8888);
TcpClient clientsocket = default(TcpClient);
Byte[] bytes = new Byte[256];
serversocket.Start();
Console.WriteLine(">> Server Started");
while(true)
{
clientsocket = serversocket.AcceptTcpClient();
Console.WriteLine("Accepted Connection From Client");
LineMatcher lm = new LineMatcher(clientsocket);
Thread thread = new Thread(new ThreadStart(lm.Run));
thread.Start();
Console.WriteLine("Client connected");
}
Console.WriteLine(" >> exit");
Console.ReadLine();
clientsocket.Close();
serversocket.Stop();
}
}
public class LineMatcher //I've jumbled it up here. Don't know what exactly to do..
{
public string fileName = "c:/myfile2.txt";
private TcpClient _client;
public LineMatcher(TcpClient client)
{
_client = client;
}
public void Run()
{
try
{
StreamReader sr = new StreamReader("c:/myfile2.txt");
using (var reader = new StreamReader(_client.GetStream()))
{
string line ="";
int lineNumber = 0;
while (null != (line = sr.ReadLine()))
{
lineNumber += 1;
byte[] data = new byte[1024];
NetworkStream stream = _client.GetStream();
//if (line.Equals(line))
for (int ct = stream.Read(data,0, data.Length-1); 0 < ct; ct = stream.Read(data,0,data.Length-1))
line += Encoding.ASCII.GetString(data, 0, ct);
line = line.Trim();
{
lineNumber.ToString();
data = Encoding.ASCII.GetBytes(line);
_client.Client.Send(data, data.Length, SocketFlags.None);
Console.WriteLine("Line {0} matches {1}", lineNumber, line);
}
}
}
}
catch (Exception ex)
{
Console.Error.WriteLine(ex.ToString());
}
Console.WriteLine("Closing client");
_client.Close();
}
}
I think you got some pieces in your Run-method swapped - here is a version that should do the job:
public void Run()
{
byte[] data;
try
{
using (var r = new StreamReader("c:/myfile2.txt"))
{
string line ="";
int lineNumber = 0;
while (null != (line = r.ReadLine()))
{
data = Encoding.ASCII.GetBytes(line + "\n");
_client.Client.Send(data, data.Length, SocketFlags.None);
}
}
}
catch (Exception ex)
{
Console.Error.WriteLine(ex.ToString());
}
Console.WriteLine("Closing client");
_client.Close();
}
Please note that I'm not 100% sure what you are trying to do (I think you want your textfile send line-by-line to your Terminal) - so you might have to change some bits here and there.
Don't know where the Stream-messes in your code came from but I guess you tried various tutorials/snippets and forgot to clean up ;)
I have a simple multithreaded C# server and client. When just one client is connected I can interact with it fine, but when two or more are connected, it seems I am using the last NetworkStream. What I'd like to be able to do is give an input command that specifies the stream to read and write to. So, for example, the first client is "Client 1" and the second client is "Client 2." I'd just type "Client 2" into my command textbox and it will get the stream for the second client.
The problem is, I don't know how to assign the text to the clients. Here is the relevant code from the server:
private void ClientThread(Object client)
{
NetworkStream networkStream = ((TcpClient)client).GetStream();
Dictionary<int, NetworkStream> myClients = new Dictionary<int, NetworkStream>(); // This didn't work.
myClients.Add(counter, ((TcpClient)client).GetStream()); // Wouldn't write.
counter = counter + 1;
streamReader = new StreamReader(networkStream);
streamWriter = new StreamWriter(networkStream);
strInput = new StringBuilder();
while (true)
{
try
{
strInput.Append(streamReader.ReadLine());
strInput.Append("\r\n");
}
catch (Exception error)
{
break;
}
Application.DoEvents();
DisplayMessage(strInput.ToString());
strInput.Remove(0, strInput.Length);
}
}
private void textBox2_KeyDown(object sender, KeyEventArgs e)
{
try
{
if (e.KeyCode == Keys.Enter)
{
//ListView.SelectedListViewItemCollection stuff = listView1.SelectedItems;
//ip is displayed in listView1, if I could also bind the stream for the ip
//to it and select it, that would be cool.
{
strInput.Append(textBox2.Text.ToString());
streamWriter.WriteLine(strInput);
streamWriter.Flush();
strInput.Remove(0, strInput.Length);
if (textBox2.Text == "cls") textBox1.Text = "";
textBox2.Text = "";
}
}
}
catch (Exception error) { }
}
So, how can I do this?
NetworkStream networkStream = myClients[2];
using(streamWriter = new StreamWriter(networkStream))
{
streamWriter.WriteLine("hello client 2"); // send something to Client 2
}
networkStream = myClients[4];
using(streamWriter = new StreamWriter(networkStream))
{
streamWriter.WriteLine("hello client 4"); // send something to Client 4
}
You are obviously storing all your client streams into a dictionary. Just load that stream into a StreamWriter and send your data.
Make your dictionary myClients class field and then just get your currently active stream like above.