When trying to receive a string or file content (as string) via TCP I am stuck with an issue wher the receiving works in general, but the line
print("TCP -> Data received:\n" + file + "\n\n" + totalrecbytes + " Bytes");
is kind of stalled until I activelly disconnect from the server side. Than it works as expected.
I debugged and receiving the data inside the
while ((recBytes = netstream.Read(bytes, 0, bytes.Length)) > 0)
loop works just fine. It also ends the loop in the correct moment. But after that simply nothing happens. I get no errors, am not "trapped" in any loop but also do not get the expected output of
print("TCP -> Data received:\n" + file + "\n\n" + totalrecbytes + " Bytes");
until I disconnect from the server side. Than I see the expected output and the client is disconnected.
Here is the implementation (original source)
private Thread _tcpThread;
private TcpClient _socketConnection;
public void Connect()
{
try
{
_tcpThread = new Thread(ReciveDataClient);
_tcpThread.IsBackground = true;
_tcpThread.Start();
}
catch (Exception e)
{
print(e.Message);
}
}
private void ReciveDataClient()
{
try
{
_socketConnection = new TcpClient("xxx.xxx.xxx.xxx", 54321);
print(this, "TCP -> Connection Success!");
}
catch (Exception e)
{
print("connection error: " + e.Message)
return;
}
try
{
var bytes = new byte[BUFFER_SIZE];
while (_socketConnection.Connected)
{
if (_socketConnection.Available <= 0) continue;
// Get a stream object for reading
var netstream = _socketConnection.GetStream();
int totalrecbytes = 0;
int recBytes;
string file = "";
// Read incomming stream into byte arrary.
while ((recBytes = netstream.Read(bytes, 0, bytes.Length)) > 0)
{
var incommingData = new byte[recBytes];
Array.Copy(bytes, 0, incommingData, 0, recBytes);
// Convert byte array to string message.
var serverMessage = Encoding.ASCII.GetString(incommingData);
file += serverMessage;
totalrecbytes += recBytes;
}
print("TCP -> Data received:\n" + file + "\n\n" + totalrecbytes + " Bytes");
netstream.Close();
}
print("TCP -> connection was terminated by the server");
}
catch (Exception e)
{
print(e.Message)
return;
}
}
I would expect that I can maintain the connection alive but still receive the data correctly and communicate with the server on a persistent TCP connection.
What am I missing or doing wrong here?
The only workarround I could find so far is allways disconnect from the server side after sending data and in my code wrap the whole ReceiveDataClient in a while loop like
private void ReciveDataClient()
{
while (true)
{
try
{
_socketConnection = new TcpClient(_server.ToString(), _server.Port);
//...
in order to immediately start a new connection after the server sent some data and disconnected the client.
Thanks to the help of Damien_The_Unbeliever and Immersive I could figure it out. It really helps to read the docs from time to time especially if it is the first time you use something ^^
NetworkStream.Read is a blocking call and as the doc states
returns: The number of bytes read from the NetworkStream, or 0 if the socket is closed.
so ofcourse the while loop actually never terminated.
So adopting the example provided there worked for me except that if the server ended the connection I got another issue so instead of checking for _socketConnection.IsConnected I used the marked answer from this post so all together this works for me now
private Thread _tcpThread;
private TcpClient _socketConnection;
public void Connect()
{
if(_socketConnection != null) return;
try
{
_tcpThread = new Thread(ReciveDataClient);
_tcpThread.IsBackground = true;
_tcpThread.Start();
}
catch (Exception e)
{
print("TCP -> Thread error: " + e.Message);
}
}
public void Disconnect()
{
if(_socketConnection = null) return;
_tcpThread.Abort();
}
private void ReciveDataClient()
{
try
{
_socketConnection = new TcpClient("xxx.xxx.xxx.xxx", 54321);
print(this, "TCP -> Connection Success!");
}
catch (Exception e)
{
print("TCP -> connection error: " + e.Message)
return;
}
try
{
while(true)
{
// Get a stream object for reading
var netstream = _socketConnection.GetStream();
//Check if still connected
if(_socketConnection.Client.Poll(0, SelectMode.SelectRead))
{
byte[] buff = new byte[1];
if( _socketConnection.Client.Receive( buff, SocketFlags.Peek ) == 0 )
{
// Server disconnected or connection lost
break;
}
}
// Check to see if this NetworkStream is readable.
if(myNetworkStream.CanRead)
{
byte[] myReadBuffer = new byte[BUFFER_SIZE];
StringBuilder myCompleteMessage = new StringBuilder();
int numberOfBytesRead = 0;
int totalBytesReceived = 0;
// Incoming message may be larger than the buffer size.
do
{
numberOfBytesRead = myNetworkStream.Read(myReadBuffer, 0, myReadBuffer.Length);
myCompleteMessage.AppendFormat("{0}", Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead));
totalBytesReceived += numberOfBytesRead;
}
while(myNetworkStream.DataAvailable);
// Print out the received message to the console.
print("TCP -> Data received:\n" + myCompleteMessage.ToString() + "\n\n" + totalrecbytes + " Bytes");
}
else
{
//Prevent a direct loop
Thread.Sleep(100);
}
}
print("TCP -> connection was terminated by the server");
}
catch(ThreadAbortException)
{
print("TCP -> Disconnected");
}
catch(Exception e)
{
print(e.Message)
}
// Clean up
_socketConnection?.Close();
_socketConnection?.Dispose();
_socketConnection = null;
}
Related
My connection handler is below (this is more for personal experimentation than production code)
If I don't add a Thread.Sleep anywhere in the while loop, it starts sucking down CPU.. Conversely, if I do Sleep to alleviate the endless while-spam, I miss the disconnection.. The CPU goes up in direct proportion to the number of clients/threads running, so it's not the listener itself that's causing the high usage, it's the actual client thread posted below.. Anyone have any ideas on how to solve this?
(I'm avoiding await-based solutions as I'm not familiar enough with async/await and the threaded method is working fine for this rather small project)
I only briefly searched around SO looking for a solution and didn't notice any that were this specific problem or that provided a solution other than directing folks to async/await articles, so sorry if I did miss an applicable answer.
private void HandleConnection(CancellationToken ct) {
int recv = 0;
byte[] buf = new byte[4096];
Trace.WriteLine($"{_name} Connected");
if (_ns.CanWrite && _client.Connected) {
_ns.Write(Encoding.BigEndianUnicode.GetBytes("■WEL"), 0, Encoding.BigEndianUnicode.GetBytes("■WEL").Length);
try {
while (_client.Connected && !ct.IsCancellationRequested) {
while (!_ns.DataAvailable) { //first attempted solution
Thread.Sleep(100); // miss discon if i sleep here
}
if (ct.IsCancellationRequested) {
Trace.WriteLine($"{(string)this} thread aborting");
break;
}
buf = new byte[4096];
if (_client.Connected && _ns.DataAvailable) {
recv = _ns.Read(buf, 0, buf.Length);
} else {
recv = 0;
}
if (recv > 0) {
string r = Encoding.BigEndianUnicode.GetString(buf);
r = r.TrimEnd('\0');
if (String.IsNullOrEmpty(r) || String.IsNullOrWhiteSpace(r))
r = null; //need the !not version
else
if (ParseMsg(r))
break;
}
//Thread.Sleep(100); // also miss discon here too
}
} catch (IOException ioe) { }
Trace.WriteLine($"{_name} Disconnected");
if (OnDisconnected != null)
OnDisconnected(this);
}
}
The proper way to communicate over a socket is:
Continuously read. These reads will block until data comes in or until the socket is gracefully disconnected (detectable by a read completing with 0 bytes read).
Periodically write. These writes are required to ensure the connection is still viable.
A proper threading approach requires two threads per connection. I'm not convinced that it's simpler than an asynchronous approach.
P.S. If your code uses Connected, then it has a bug. Proper solutions never need to use Connected.
I had the same problema than you but I found that the best way to solve this problem is:
Not Blocking the Socket with sleeps and thread.
UPGRADE: If you use threads and sleeps into your server, it will suffer a low performance to receive and answer each message by each connection.
If you want an High Performance App you must not use sleeps or create thread for each connection that you accept. The best way is using the Asyncronous methods that NetworkStream provides, using BeginRead and EndRead, for example:
public void run()
{
server = new TcpListener(IPAddress.Any, port);
server.Start();
log.Info("Starting SocketServer on Port [" + port + "]");
while (keepRunning)
{
try
{
TcpClient socket = server.AcceptTcpClient();
if (keepRunning)
RequestManager.createRequestForEvalue(socket, idLayout);
}
catch (Exception ex)
{
log.Error(ex.Message);
log.Error(ex.StackTrace);
}
}
log.Info("Server Stoped.");
}
public static bool createRequestForEvalue(TcpClient socket, int idLayout)
{
Request req = null;
req = new Request(socket,idLayout);
registerRequest(req.ID,req); //Registra el Request, para su posterior uso.
// DO NOT CREATE THREADS FOR ATTEND A NEW CONNECTION!!!
//Task.Factory.StartNew(req.RunForIVR);
//ThreadPool.QueueUserWorkItem(req.RunForIVR);
req.startReceiveAsync(); //Recive data in asyncronus way.
return true;
}
public void startReceiveAsync()
{
try
{
log.Info("[" + id + "] Starting to read the Request.");
requestBuffer = new byte[BUFFER_SIZE];
NetworkStream nst = socket.GetStream();
nst.BeginRead(requestBuffer, 0,BUFFER_SIZE, this.requestReceived, nst);
}catch(Exception ex)
{
log.Error("[" + id + "] There was a problem to read the Request: " + ex.Message);
RequestManager.removeRequest(id);
closeSocket();
}
}
public void requestReceived(IAsyncResult ar)
{
try
{
NetworkStream nst = socket.GetStream();
int bread = nst.EndRead(ar); //Block the socket until all the buffer has been available.
message = Encoding.UTF8.GetString(requestBuffer, 0, BUFFER_SIZE);
log.Info("[" + id + "] Request recived: [" + message +"]");
RunForIVR();
}
catch (Exception ex)
{
log.Error("[" + id + "] There was a problem to read the Request: " + ex.Message);
RequestManager.removeRequest(id);
closeSocket();
}
}
public void SendResponse(String Response)
{
StringBuilder sb = new StringBuilder();
sb.Append(Response);
sb.Append('\0', BUFFER_SIZE - Response.Length);
string message = sb.ToString();
log.Info("[" + id + "] ivrTrans CMD: [" + idCMD + "] RESPONSE: [" + Response + "]");
NetworkStream nst = socket.GetStream();
byte[] buffer = new byte[BUFFER_SIZE];
for (int i = 0; i < BUFFER_SIZE; i++)
buffer[i] = (byte)message.ElementAt(i);
nst.BeginWrite(buffer, 0, BUFFER_SIZE, this.closeSocket, nst);
}
public void closeSocket(IAsyncResult ar = null)
{
try
{
if (ar != null) //Since 4.24
{
NetworkStream nst = socket.GetStream();
nst.EndWrite(ar);
}
socket.Close();
socket = null;
}catch(Exception ex)
{
log.Warn("[" + id + "] There was a problem to close the socket. Error: " + ex.Message + Environment.NewLine + ex.StackTrace);
}
log.Info("[" + id + "] Socket closed.");
}
Upgrade I use the EndRead to be sure that the request has been arrived at all.
By Other way, you can use BeginWrite and EndWrite to know when the socket has been finished of write to close the connection
In this way you are attended the connection in a continues way and as soon as possible. In my case i reduce the CPU usage from 30% to 0%, for an a mount of 15K request per hour.
I have this web server program up and running, using TcpListener. The problem is that for each get request made through web browser (or chrome Postman extension), it captures two requests.
namespace Server
{
class WebServer2
{
private TcpListener listener;
private int port = 8080;
public WebServer2()
{
try
{
listener = new TcpListener(IPAddress.Parse("127.0.0.1"), port);
listener.Start();
Console.WriteLine("Listening...");
//start the thread which calls the method 'StartListen'
Thread th = new Thread(new ThreadStart(StartListen));
th.Start();
}
catch (Exception e)
{
Console.WriteLine("An Exception Occurred While Listening: " + e.ToString());
}
}
//Recieve Request
public void StartListen()
{
int iStartPos = 0;
String sRequest;
String sRequestedFile;
String sResponse = "";
while (true)
{
//Accept a new connection
Socket socket = listener.AcceptSocket();
if (socket.Connected)
{
Console.WriteLine("\nClient Connected");
Console.WriteLine("----------------");
//Receive data from the client
Byte[] bReceive = new Byte[1024];
int i = socket.Receive(bReceive, bReceive.Length, 0);
//Convert Byte to String
string sBuffer = Encoding.ASCII.GetString(bReceive);
//Only GET Request is accepted
if (sBuffer.Substring(0, 3) != "GET")
{
Console.WriteLine("Not a Get Request.");
socket.Close();
continue;
}
// Look for HTTP request
iStartPos = sBuffer.IndexOf("HTTP", 1);
// Get the HTTP text and version e.g. it will return "HTTP/1.1"
string sHttpVersion = sBuffer.Substring(iStartPos, 8);
// Extract the Requested Type and Requested file/directory
sRequest = sBuffer.Substring(0, iStartPos - 1);
//If file name not provided
if (sRequest.IndexOf(".") < 1)
{
Console.WriteLine("File name not Provided!");
socket.Close();
continue;
}
//Extract the requested file name
iStartPos = sRequest.LastIndexOf("/") + 1;
sRequestedFile = sRequest.Substring(iStartPos);
Console.WriteLine("Requested File: " + sRequestedFile);
int iTotBytes = 0;
sResponse = "";
FileStream fs = new FileStream(sRequestedFile, FileMode.Open, FileAccess.Read, FileShare.Read);
BinaryReader reader = new BinaryReader(fs);
byte[] bytes = new byte[fs.Length];
int read;
while ((read = reader.Read(bytes, 0, bytes.Length)) != 0)
{
// Read from the file and write the data to the network
sResponse = sResponse + Encoding.ASCII.GetString(bytes, 0, read);
iTotBytes = iTotBytes + read;
}
reader.Close();
fs.Close();
SendHeader(sHttpVersion, "text/html", iTotBytes, " 200 OK", ref socket);
SendToBrowser(bytes, ref socket);
socket.Send(bytes, bytes.Length, 0);
socket.Close();
}
}
}
// Overloaded Function, takes string, convert to bytes and calls
// overloaded sendToBrowserFunction.
public void SendToBrowser(String sData, ref Socket socket)
{
SendToBrowser(Encoding.ASCII.GetBytes(sData), ref socket);
}
/// Sends data to the browser (client)
public void SendToBrowser(Byte[] bSendData, ref Socket socket)
{
int numBytes = 0;
try
{
if (socket.Connected)
{
if ((numBytes = socket.Send(bSendData, bSendData.Length, 0)) == -1)
Console.WriteLine("Socket Error");
}
else
Console.WriteLine("Connection Dropped!");
}
catch (Exception e)
{
Console.WriteLine("Error: {0} ", e);
}
}
// This function send the Header Information to the client (Browser)
public void SendHeader(string sHttpVersion, string sMIMEHeader, int iTotBytes, string sStatusCode, ref Socket socket)
{
String sBuffer = "";
Byte[] bSendData;
if (sStatusCode.Equals("404") || sStatusCode.Equals("400"))
{
sBuffer = sBuffer + sHttpVersion + sStatusCode + "\r\n";
sBuffer = sBuffer + "Server: MyServer\r\n";
sBuffer = sBuffer + "Content-Length: " + 0 + "\r\n\r\n";
bSendData = Encoding.ASCII.GetBytes(sBuffer);
SendToBrowser(bSendData, ref socket);
}
else
{
sBuffer = sBuffer + sHttpVersion + sStatusCode + "\r\n";
sBuffer = sBuffer + "Server: MyServer\r\n";
sBuffer = sBuffer + "Content-Type: " + sMIMEHeader + "\r\n";
sBuffer = sBuffer + "Accept-Ranges: bytes\r\n";
sBuffer = sBuffer + "Content-Length: " + iTotBytes + "\r\n\r\n";
bSendData = Encoding.ASCII.GetBytes(sBuffer);
SendToBrowser(bSendData, ref socket);
}
}
}
}
Single request made by chrome against http://localhost:8080/page1.html
Request made by Postman Extension
The funny thing is, everything works find when I send request through my client program (using TcpClient).
I tested your server and got similar results:
Chrome automatically asks for a favicon.ico file for every request. This generates the extra GET request to your server.
Firefox doesn't do this and simply generates one request per refresh.
Then there is a second problem I experienced, which is the one in your Postman screenshot.
Chrome (including the Postman Extension running inside it) reconnects
without sending anything, so the server "hangs" until you get a
response filled with \0 (nul-characters).
This is part of Chrome's prediction service to load subsequent requests faster. You could disable this behavior under Settings (advanced) > Privacy:
In your server implementation, this results in the "Not a Get Request" output if no subsequent GET request follows (instead, Chrome sends \0 to signal its not sending anything anyway).
Note: I didn't experience any of this in the actual Postman application.
While the server waits for chrome to send a request, it cannot service any other requests. To prevent this from happening, consider using an asynchronous approach.
I'm trying to learn network programming and I'm trying to create a TCP server and TCP client.
The server will start and listen for connections. The client will connect and send a string to the server.
Then server will reply with a string containing the received string.
The issue I'm facing is that for the first try this works but after that sometimes the client receive an empty reply.
Below is the code for the server:
public void handlerThread()
{
TcpClient TcpClient = clients[clients.Count - 1];
NetworkStream networkStream = TcpClient.GetStream();
int i = -1;
while (TcpClient.Connected )
{
Byte[] data = new Byte[1024];
if ((i=networkStream.Read(data, 0, data.Length)) != 0)
{
string incomingMessage = Encoding.ASCII.GetString(data);
Debug.WriteLine("DDB Server incomingMessage: " + incomingMessage);
this.Invoke((MethodInvoker)(() => lbMessage.Items.Add("Message received is: " + incomingMessage)));
// Send back a response.
data = new Byte[1024];
string outMessage = string.Empty;
outMessage = "Recieved msg: " + incomingMessage;
data = System.Text.Encoding.ASCII.GetBytes(outMessage);
networkStream.Write(data, 0, data.Length);
Debug.WriteLine("DDB Server Reply: " + outMessage);
this.Invoke((MethodInvoker)(() => lblStatus.Text = "Sent reply!"));
}
}
}
The client's code:
private void button2_Click(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(_txtBoxMsg.Text))
{
try
{
Byte[] data = System.Text.Encoding.ASCII.GetBytes(_txtBoxMsg.Text);
stream = client.GetStream();
// Send the message to the connected TcpServer.
stream.Write(data, 0, data.Length);
Debug.WriteLine("DDB Client Message: " + _txtBoxMsg.Text);
data = new Byte[1024];
String responseData = String.Empty;
Int32 bytes = stream.Read(data, 0, data.Length);
responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
Debug.WriteLine("DDB Client recieved: " + responseData);
lbMsgs.Items.Add(string.Format("Received: {0}", responseData));
}
catch (ArgumentNullException ex)
{
MessageBox.Show("ArgumentNullException: " + ex); ;
}
catch (SocketException ex)
{
MessageBox.Show("SocketException: " + ex);
}
}
else
MessageBox.Show("You did not enter a message to be sent to server!", "Please enter a message", MessageBoxButtons.OK);
}
I noticed something while using Debug.WriteLine() the first run the message is displayed correctly. after that the messages are next to each other (as if I was using Debug.Write()).
Could it be that the byte representation for the messages is being corrupted (for example the return character or something)?
I'm trying to make a server client using a local console server on my pc and a client on windows phone 8.1. The problem that I have is that I don't know how to read the incoming data from the client. I've searched the internet and read serveral microsoft tutorials but they do not explain how to read the incoming data in the server. Here's what I have.
Client on windows phone 8.1:
private async void tryConnect()
{
if (connected)
{
StatusLabel.Text = "Already connected";
return;
}
try
{
// serverHostnameString = "127.0.0.1"
// serverPort = "1330"
StatusLabel.Text = "Trying to connect ...";
serverHost = new HostName(serverHostnameString);
// Try to connect to the
await clientSocket.ConnectAsync(serverHost, serverPort);
connected = true;
StatusLabel.Text = "Connection established" + Environment.NewLine;
}
catch (Exception exception)
{
// If this is an unknown status,
// it means that the error is fatal and retry will likely fail.
if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown)
{
throw;
}
StatusLabel.Text = "Connect failed with error: " + exception.Message;
// Could retry the connection, but for this simple example
// just close the socket.
closing = true;
// the Close method is mapped to the C# Dispose
clientSocket.Dispose();
clientSocket = null;
}
}
private async void sendData(string data)
{
if (!connected)
{
StatusLabel.Text = "Must be connected to send!";
return;
}
UInt32 len = 0; // Gets the UTF-8 string length.
try
{
StatusLabel.Text = "Trying to send data ...";
// add a newline to the text to send
string sendData = "jo";
DataWriter writer = new DataWriter(clientSocket.OutputStream);
len = writer.MeasureString(sendData); // Gets the UTF-8 string length.
// Call StoreAsync method to store the data to a backing stream
await writer.StoreAsync();
StatusLabel.Text = "Data was sent" + Environment.NewLine;
// detach the stream and close it
writer.DetachStream();
writer.Dispose();
}
catch (Exception exception)
{
// If this is an unknown status,
// it means that the error is fatal and retry will likely fail.
if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown)
{
throw;
}
StatusLabel.Text = "Send data or receive failed with error: " + exception.Message;
// Could retry the connection, but for this simple example
// just close the socket.
closing = true;
clientSocket.Dispose();
clientSocket = null;
connected = false;
}
}
(from http://msdn.microsoft.com/en-us/library/windows/apps/xaml/jj150599.aspx)
And the server:
public class Server
{
private TcpClient incomingClient;
public Server()
{
TcpListener listener = new TcpListener(IPAddress.Parse("127.0.0.1"), 1330);
listener.Start();
Console.WriteLine("Waiting for connection...");
while (true)
{
//AcceptTcpClient waits for a connection from the client
incomingClient = listener.AcceptTcpClient();
//start a new thread to handle this connection so we can go back to waiting for another client
Thread thread = new Thread(HandleClientThread);
thread.IsBackground = true;
thread.Start(incomingClient);
}
}
private void HandleClientThread(object obj)
{
TcpClient client = obj as TcpClient;
Console.WriteLine("Connection found!");
while (true)
{
//how to read and send data back?
}
}
}
It comes to the point where the server prints 'Connection found!', but I don't know how to go further.
Any help is appreciated!
EDIT:
Now my handleclientthread method looks like this:
private void HandleClientThread(object obj)
{
TcpClient client = obj as TcpClient;
netStream = client.GetStream();
byte[] rcvBuffer = new byte[500]; // Receive buffer
int bytesRcvd; // Received byte count
int totalBytesEchoed = 0;
Console.WriteLine("Connection found!");
while (true)
{
while ((bytesRcvd = netStream.Read(rcvBuffer, 0, rcvBuffer.Length)) > 0)
{
netStream.Write(rcvBuffer, 0, bytesRcvd);
totalBytesEchoed += bytesRcvd;
}
Console.WriteLine(totalBytesEchoed);
}
}
But it still doesn't write the bytes to the console
So... after a lot of searching the internet I have found a solution...
Server: to read from the server and send data back to the phone:
// method in a new thread, for each connection
private void HandleClientThread(object obj)
{
TcpClient client = obj as TcpClient;
netStream = client.GetStream();
Console.WriteLine("Connection found!");
while (true)
{
// read data
byte[] buffer = new byte[1024];
int totalRead = 0;
do
{
int read = client.GetStream().Read(buffer, totalRead, buffer.Length - totalRead);
totalRead += read;
} while (client.GetStream().DataAvailable);
string received = Encoding.ASCII.GetString(buffer, 0, totalRead);
Console.WriteLine("\nResponse from client: {0}", received);
// do some actions
byte[] bytes = Encoding.ASCII.GetBytes(received);
// send data back
client.GetStream().WriteAsync(bytes, 0, bytes.Length);
}
}
Phone(client): to send messages from the phone and read the messages from server:
private async void sendData(string dataToSend)
// import for AsBuffer(): using System.Runtime.InteropServices.WindowsRuntime;
{
if (!connected)
{
StatusLabel.Text = "Status: Must be connected to send!";
return;
}
try
{
byte[] data = GetBytes(dataToSend);
IBuffer buffer = data.AsBuffer();
StatusLabel.Text = "Status: Trying to send data ...";
await clientSocket.OutputStream.WriteAsync(buffer);
StatusLabel.Text = "Status: Data was sent" + Environment.NewLine;
}
catch (Exception exception)
{
if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown)
{
throw;
}
StatusLabel.Text = "Status: Send data or receive failed with error: " + exception.Message;
closing = true;
clientSocket.Dispose();
clientSocket = null;
connected = false;
}
readData();
}
private async void readData()
{
StatusLabel.Text = "Trying to receive data ...";
try
{
IBuffer buffer = new byte[1024].AsBuffer();
await clientSocket.InputStream.ReadAsync(buffer, buffer.Capacity, InputStreamOptions.Partial);
byte[] result = buffer.ToArray();
StatusLabel.Text = GetString(result);
}
catch (Exception exception)
{
if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown)
{
throw;
}
StatusLabel.Text = "Receive failed with error: " + exception.Message;
closing = true;
clientSocket.Dispose();
clientSocket = null;
connected = false;
}
}
The 'await clientSocket.InputStream.ReadAsync(buffer, buffer.Capacity, InputStreamOptions.Partial)' command in the readData method was very unclear for me. I didn't know you had to make a new buffer, and the ReadAsync-method fills it(as i inderstand it). Found it here: StreamSocket.InputStreamOptions.ReadAsync hangs when using Wait()
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
NullReferenceException on instanciated object?
What is a NullReferenceException in .NET?
I have built a TCP client in C#, when the client cannot connect Im getting the below.
I keep getting a NullReference Exception with the following code, I cannot figure how to catch it or stop it.. any help will be greatly appreciated.
Its happening at "int a = sReponseData.Length"
{
string sMesg = "LogOn Ext:" + txtdevice.Text;
SendMessage(sMesg);
int a = sResponseData.Length;
//Geting the Script out of the message.
if (a > 10)
{
string stemp = sResponseData;
string[] sSplit = stemp.Split(new Char[] { ';'});
foreach (string s in sSplit)
{
if ((s.Trim() != "Tag") & (s.Trim() != "StopStart"))
sScript = s;
}
}
}
}
and here is the sMesg
{
InitializeComponent();
try
{
// Create a TcpClient.
// Note, for this client to work you need to have a TcpServer
// connected to the same address as specified by the server, port
// combination.
//Int32 port = 13000;
TcpClient client = new TcpClient("127.0.0.1", 32111);
// Translate the passed message into ASCII and store it as a Byte array.
Byte[] data = System.Text.Encoding.ASCII.GetBytes(sMsg);
// Get a client stream for reading and writing.
// Stream stream = client.GetStream();
NetworkStream stream = client.GetStream();
// Send the message to the connected TcpServer.
stream.Write(data, 0, data.Length);
//MessageBox.Show("Sent: {0}" + sMsg);
// Receive the TcpServer.response.
// String to store the response ASCII representation.
sResponseData = String.Empty;
if (stream.CanRead)
{
byte[] myReadBuffer = new byte[1024];
StringBuilder myCompleteMessage = new StringBuilder();
int numberOfBytesRead = 0;
// Incoming message may be larger than the buffer size.
do
{
numberOfBytesRead = stream.Read(myReadBuffer, 0, myReadBuffer.Length);
myCompleteMessage.AppendFormat("{0}", Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead));
}
while (stream.DataAvailable);
// Print out the received message to the console.
sResponseData = myCompleteMessage.ToString();
//MessageBox.Show(sResponseData);
}
else
{
sResponseData = ("3");
MessageBox.Show("TagIt Server is unavalible at this moment.");
}
// Close everything.
stream.Close();
client.Close();
}
catch (ArgumentNullException e)
{
WriteLog("ArgumentNullException: {0}" + e);
MessageBox.Show("TagIt Server is unavalible at this moment.");
}
catch (SocketException e)
{
WriteLog("SocketException: {0}" + e);
MessageBox.Show("TagIt Server is unavalible at this moment.");
}
}
You can check if Response data has value or not:
Something like:
int a;
try
{
if(sResponseData==null || sResponseData=="" )
{
MessageBox.Show("ResponseData is NULL or Empty"); //Shows Error
}
else
{
//SresponseData has value
string sMesg = "LogOn Ext:" + txtdevice.Text;
SendMessage(sMesg);
a= Convert.ToInt32(sResponseData).Length;
//Geting the Script out of the message.
if (a > 10)
{
string stemp = sResponseData;
string[] sSplit = stemp.Split(new Char[] { ';'});
foreach (string s in sSplit)
{
if ((s.Trim() != "Tag") & (s.Trim() != "StopStart"))
sScript = s;
}
}
}
}
catch (Execption ex)
{
MessageBox.Show(ex.Message); //Shows Error
}
Before checking length of sResponseData make sure you check whether sResponseData is null or not.