My program freeze, before reading from NetworkStream - c#

Hello I am a student and I'm not used to c# yet. I am writing a program with server and client, which are connected with socket. I am trying to implement a way to read from stream, when data is available, with while loop. I can avoid chrashing if I show message with MessageBox.Show() before reading/writing stream. I don't know why program without displayed message isn't working...
public partial class Form1 : Form
{
const int port = 22222;
const string ip = "127.0.0.1";
IPAddress ipServer = IPAddress.Parse(ip);
TcpListener server = null;
TcpClient client = null;
Thread thServer = null;
Thread thClient = null;
NetworkStream dataStream = null;
const int a = 11;
const int n = 251;
string receivedMessage = "";
bool? izbira = null;
public Form1()
{
InitializeComponent();
thServer = new Thread(new ThreadStart(startServer));
thServer.IsBackground = true;
thServer.Start();
}
void startServer() {
server = new TcpListener(ipServer, port);
server.Start();
textBox4.Invoke(new Action(() => textBox4.AppendText("Strežnik: zagnan na: IP: " + ip + ", port:" + port)));
client = new TcpClient();
client = server.AcceptTcpClient();
NetworkStream dataStream = client.GetStream();
textBox4.Invoke(new Action(() => textBox4.AppendText(Environment.NewLine + "Strežnik: Sprejet nov uporabnik")));
if (izbira == true)
{
byte[] message = new byte[1024];
if(dataStream.DataAvailable)
dataStream.Read(message, 0, message.Length);
receivedMessage = Encoding.UTF8.GetString(message);
textBox4.Invoke(new Action(() => textBox4.AppendText(Environment.NewLine + "Strežnik: Dobil sem sporočilo: " + receivedMessage)));
message = new byte[1024];
message = Encoding.UTF8.GetBytes("drugo sporocilo!");
dataStream.Write(message, 0, message.Length);
}
else {
byte[] message = new byte[1024];
message = Encoding.UTF8.GetBytes("serbus");
dataStream.Write(message, 0, message.Length);
}
}
void button1_Click(object sender, EventArgs e) {
if (izbira == null) {
textBox4.Invoke(new Action(() => textBox4.AppendText(Environment.NewLine + "Izbrati morate ali boste datoteko prenesli ali poslali!")));
return;
}
this.button1.Enabled = false;
client = new TcpClient();
IPAddress insertedIp = IPAddress.Parse(textBox1.Text);
client.Connect(insertedIp, Convert.ToInt32(textBox3.Text));
dataStream = client.GetStream();
if (izbira == true)
{
byte[] message = new byte[1024];
message = Encoding.UTF8.GetBytes("hejj");
dataStream.Write(message, 0, message.Length);
message = new byte[1024];
MessageBox.Show("");
while (true)
{
if (dataStream.DataAvailable)
{
dataStream.Read(message, 0, message.Length);
break;
}
}
receivedMessage = Encoding.UTF8.GetString(message);
textBox4.Invoke(new Action(() => textBox4.AppendText(Environment.NewLine + "Strežnik: Dobil sem sporočilo: " + receivedMessage)));
}
else {
byte[] message = new byte[1024];
MessageBox.Show("Serbus");
while (true)
{
if (dataStream.DataAvailable)
{
dataStream.Read(message, 0, message.Length);
break;
}
}
receivedMessage = Encoding.UTF8.GetString(message);
textBox4.Invoke(new Action(() => textBox4.AppendText(Environment.NewLine + "Strežnik: Dobil sem sporočilo: " + receivedMessage)));
}
}
void buttonUpload_Click(object sender, EventArgs e) {
izbira = true;
this.buttonDownload.Enabled = false;
}
void buttonDownload_Click(object sender, EventArgs e) {
izbira = false;
this.buttonUpload.Enabled = false;
this.button2.Text = "Prenesi";
}

Now this is mostly guessing, as we barely have enough code to say anything for certain:
What about the JiT Compiler?
One of it's purposes is dead code detection. It cuts out code it predicts will not have an effect. Unfortunately, it is still only a computer programm, so false positives happen. For example, trying to force a OOM Exception for x32 Framework installations, I had to go out of my way to not have the code cut out by the JiT:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace OOM_32_forced
{
class Program
{
static void Main(string[] args)
{
//each short is 2 byte big, Int32.MaxValue is 2^31.
//So this will require a bit above 2^32 byte, or 2 GiB
short[] Array = new short[Int32.MaxValue];
/*need to actually access that array
Otherwise JIT compiler and optimisations will just skip
the array definition and creation */
foreach (short value in Array)
Console.WriteLine(value);
}
}
}
A MessageBox will prevent this whole function from being cut out as dead code. Outputting something towards the user is alwasy asumed to "have a effect". However seperate parts of it are still eligible for dead code detection.
Unforunately you have not provided us with a minimal, complete verifyable example. So we can not really help you figure it out any further.

Related

C# Client.SendFile() separating stream

Please bear in mind I am new to C# language and networking so forgive me if this might sound obvious.
I'm just in the process of understanding TCP clients and how to separate streams...
In this example, I have 3 sets of data that I want to send...
is a CMD output:
private void CmdOutputDataHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
StringBuilder strOutput = new StringBuilder();
if (!String.IsNullOrEmpty(outLine.Data))
{
try
{
strOutput.Append(outLine.Data);
buffer = encoder.GetBytes("2 " + outLine.Data+ "\r\n");
networkStream = newclient.GetStream();
networkStream.Write(buffer, 0, buffer.Length);
networkStream.Flush();
}
catch (Exception err) { }
}
}
Which returns as a first stream the following:
With a prebuffer as number 2(To separate the data)
The second Is a simple get info:
private void GetClientinfo()
{
networkStream = newclient.GetStream();
buffer = encoder.GetBytes("1 " + Environment.MachineName +"\n"+"Connected");
networkStream.Write(buffer, 0, buffer.Length);
networkStream.Flush();
}
Which then sends the following :
So then my stream ends up being separated:
My issue is then that I try to send a file with the following script:
private void sendFile()
{
// Create the preBuffer data.
string string1 = String.Format("9 ");
byte[] preBuf = Encoding.ASCII.GetBytes(string1);
// Create the postBuffer data.
string string2 = String.Format("");
byte[] postBuf = Encoding.ASCII.GetBytes(string2);
string filePath = #"\Users\nico_\Documents\transfer_ex.txt";
newclient.Client.SendFile(filePath, preBuf, postBuf, TransmitFileOptions.UseDefaultWorkerThread);
}
As you can see, it ends up getting jumbled up with the second stream being sent...
What would be the cause of this?
FULL SERVER SCRIPT:
public partial class Form1 : Form
{
TcpListener tcpListener = new TcpListener(System.Net.IPAddress.Any, 6666);
private int appStatus = 0;
TcpClient client;
TcpClient streamData;
List<TcpClient> clientList = new List<TcpClient>();
NetworkStream networkStream;
Thread th_StartListen, th_handleClient;
StringBuilder strOutput;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
th_StartListen = new Thread(new ThreadStart(StartListen));
th_StartListen.Start();
txtCmdOutput.Focus();
}
private void StartListen()
{
//Creating a TCP Connection and listening to the port
tcpListener = new TcpListener(System.Net.IPAddress.Any, 6666);
tcpListener.Start();
toolStripStatusLabel1.Text = "Listening on port 6666 ...";
int counter = 0;
appStatus = 0;
while (appStatus != 2)
{
try
{
client = tcpListener.AcceptTcpClient();
counter++;
clientList.Add(client);
IPEndPoint ipend = (IPEndPoint)client.Client.RemoteEndPoint;
//Updating status of connection
toolStripStatusLabel1.Text = "Connected from "+ IPAddress.Parse(ipend.Address.ToString());
appStatus = 1;
th_handleClient = new Thread(delegate () { handleClient(client, counter); });
th_handleClient.Start();
}
catch (Exception err)
{
{
Cleanup();
}
}
}
}
private void handleClient(object client, int i)
{
try
{
TcpClient streamData = (TcpClient)client;
byte[] data = new byte[4096];
byte[] sendData = new byte[4096];
int byteRead;
string strdata;
ASCIIEncoding encode = new ASCIIEncoding();
Thread.Sleep(2000);
NetworkStream networkstream = streamData.GetStream();
//Send Command 1
sendData = encode.GetBytes("1");
networkstream.Write(sendData, 0, sendData.Length);
networkstream.Flush();
//Listen...
while (true)
{
byteRead = 1;
byteRead = networkstream.Read(data, 0, 4096);
//receiveFile();
if (networkstream.DataAvailable != true)
{
strdata = Encoding.ASCII.GetString(data, 0, byteRead);
Debug.WriteLine(strdata);
//Get user info
if (strdata.StartsWith("1"))
{
updateLabel(labelMachinename, strdata, 0);
updateLabel(labelSampleOutput, strdata, 1);
}
if (strdata.StartsWith("2"))
{
updateText(txtCmdConsole, strdata);
}
if (strdata.StartsWith("9"))
{
Debug.WriteLine(strdata);
}
//receiveFile();
}
}
}
catch (Exception err)
{
{
Cleanup();
}
}
}
private void receiveFile()
{
StreamReader reader = new StreamReader(client.GetStream());
string fileSize = reader.ReadLine();
string fileName = reader.ReadLine();
int length = Convert.ToInt32(fileSize);
byte[] buffer = new byte[length];
int received = 0;
int read = 0;
int size = 1024;
int remaining = 0;
while (received < length)
{
remaining = length - received;
if (remaining < size)
{
size = remaining;
}
read = client.GetStream().Read(buffer, received, size);
received += read;
}
// Save the file using the filename sent by the client
using (FileStream fStream = new FileStream(Path.GetFileName(fileName), FileMode.Create))
{
fStream.Write(buffer, 0, buffer.Length);
fStream.Flush();
fStream.Close();
}
Debug.WriteLine("File received and saved in " + Environment.CurrentDirectory);
}
private void txtCmdOutput_KeyDown(object sender, KeyEventArgs e)
{
try
{
if (e.KeyCode == Keys.Enter && appStatus == 1)
{
TcpClient streamData = (TcpClient)client;
byte[] sendData = new byte[4096];
ASCIIEncoding encode = new ASCIIEncoding();
NetworkStream networkstream = streamData.GetStream();
sendData = encode.GetBytes("2 "+ txtCmdOutput.Text.ToString());
networkstream.Write(sendData, 0, sendData.Length);
networkstream.Flush();
txtCmdOutput.Text = "";
}
}
catch (Exception err) {
{
Cleanup();
}
}
}
private void updateLabel(Label label,string strdata, int row)
{
label.Invoke((MethodInvoker)delegate
{
label.Text = strdata.Substring(2).Split(new char[] { '\r', '\n' })[row];
});
}
private void updateText(TextBox text, string strdata)
{
text.Invoke((MethodInvoker)delegate
{
text.AppendText(strdata.Substring(2));
});
}
private void btnKillClient_Click(object sender, EventArgs e)
{
try
{
TcpClient streamData = (TcpClient)client;
byte[] sendData = new byte[4096];
ASCIIEncoding encode = new ASCIIEncoding();
NetworkStream networkstream = streamData.GetStream();
sendData = encode.GetBytes("3");
networkstream.Write(sendData, 0, sendData.Length);
networkstream.Flush();
Cleanup();
}
catch (Exception err)
{
{
Cleanup();
}
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
System.Environment.Exit(System.Environment.ExitCode);
}
private void Cleanup()
{
try
{
toolStripStatusLabel1.Text = "Connection Lost";
}
catch (Exception err) { }
}
}
FULL CLIENT SCRIPT:
public partial class Form1 : Form
{
private int appStatus = 0;
TcpClient newclient = new TcpClient();
NetworkStream networkStream;
byte[] buffer = new byte[4096];
ASCIIEncoding encoder = new ASCIIEncoding();
Process processCmd;
Thread th_ListenToServer, th_RunServer;
public Form1()
{
InitializeComponent();
}
private void Form1_Shown(object sender, EventArgs e)
{
this.Hide();
th_ListenToServer = new Thread(new ThreadStart(ListenToServer));
th_ListenToServer.Start();
//ConnectToServer();
}
private void ListenToServer()
{
while (!newclient.Connected)
{
try
{
newclient = new TcpClient();
Debug.WriteLine("trying to connect...");
newclient = new TcpClient("127.0.0.1", 6666);
networkStream = newclient.GetStream();
th_RunServer = new Thread(new ThreadStart(RunServer));
th_RunServer.Start();
}
catch (Exception ex)
{
Debug.WriteLine("Could not connect to server");
System.Threading.Thread.Sleep(5000); //Wait 5 seconds then try again
}
}
}
private void RunServer()
{
byte[] data = new byte[4096];
int i;
string strdata;
i = 0;
CmdHandler();
sendFile();
while (newclient.Connected)
{
try
{
i = 0;
i = networkStream.Read(data, 0, data.Length);
if (i == 0) { break; }
strdata = Encoding.ASCII.GetString(data, 0, i);
Debug.WriteLine(strdata);
if (strdata == "1")
{
GetClientinfo();
}
if (strdata.StartsWith("2"))
{
//Debug.WriteLine(strdata);
processCmd.StandardInput.WriteLine(strdata.Substring(2));
}
if (strdata.StartsWith("3"))
{
StopServer();
}
if (strdata.StartsWith("4"))
{
StopServer();
}
else
{
//sendFile();
}
}
catch
{
Cleanup();
new Thread(ListenToServer).Start();
Debug.WriteLine("Attempting Reconection");
}
}
}
private void sendFile()
{
/*
// Create the preBuffer data.
string fileName = #"\Users\nico_\Documents\transfer_ex.txt";
byte[] fileNameByte = Encoding.ASCII.GetBytes(fileName);
byte[] fileNameLen= BitConverter.GetBytes(fileNameByte.Length);
byte[] fileData = File.ReadAllBytes(fileName);
byte[] clientData = new byte[4 + fileNameByte.Length + fileData.Length];
fileNameLen.CopyTo(clientData, 0);
fileNameByte.CopyTo(clientData, 4);
fileData.CopyTo(clientData, 4 + fileNameByte.Length);
networkStream = newclient.GetStream();
buffer = encoder.GetBytes("9 " + clientData);
networkStream.Write(buffer, 0, buffer.Length);
networkStream.Flush();
*/
string string1 = String.Format("9 ");
byte[] preBuf = Encoding.ASCII.GetBytes(string1);
// Create the postBuffer data.
string string2 = String.Format("");
byte[] postBuf = Encoding.ASCII.GetBytes(string2);
string filePath = #"\Users\nico_\Documents\transfer_ex.txt";
newclient.Client.SendFile(filePath, preBuf, postBuf, TransmitFileOptions.UseDefaultWorkerThread);
}
private void GetClientinfo()
{
networkStream = newclient.GetStream();
buffer = encoder.GetBytes("1 " + Environment.MachineName + "\n" + "Connected");
networkStream.Write(buffer, 0, buffer.Length);
networkStream.Flush();
}
private void CmdHandler()
{
processCmd = new Process();
processCmd.StartInfo.FileName = "cmd.exe";
processCmd.StartInfo.CreateNoWindow = true;
processCmd.StartInfo.UseShellExecute = false;
processCmd.StartInfo.RedirectStandardOutput = true;
processCmd.StartInfo.RedirectStandardInput = true;
processCmd.StartInfo.RedirectStandardError = true;
//processCmd.OutputDataReceived += CaptureOutput;
//processCmd.ErrorDataReceived += CaptureError;
processCmd.OutputDataReceived += new DataReceivedEventHandler(CmdOutputDataHandler);
processCmd.ErrorDataReceived += new DataReceivedEventHandler(CmdOutputDataHandler);
processCmd.Start();
processCmd.BeginOutputReadLine();
}
private void CmdOutputDataHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
StringBuilder strOutput = new StringBuilder();
if (!String.IsNullOrEmpty(outLine.Data))
{
try
{
strOutput.Append(outLine.Data);
buffer = encoder.GetBytes("2 " + outLine.Data + "\r\n");
networkStream = newclient.GetStream();
networkStream.Write(buffer, 0, buffer.Length);
networkStream.Flush();
}
catch (Exception err) { }
}
}
private void Cleanup()
{
try { processCmd.Kill(); } catch (Exception err) { };
networkStream.Close();
}
private void StopServer()
{
Cleanup();
System.Environment.Exit(System.Environment.ExitCode);
}
}
Your first output appends \r\n, which results in separation from the second output. The second output embeds a \n (not \r\n) and ends with nothing, which means nothing separates it from the third output.
Either add a newline after data in GetClientInfo, or add one to preBuf in sendFile().
Or switch to something less ambiguous, like length-prefixing.
Here is the answer:
CLIENT SIDE:
private void sendFile()
{
string string1 = "9";
byte[] preBuf = Encoding.ASCII.GetBytes(string1);
// Create the postBuffer data.
string string2 = "";
byte[] postBuf = Encoding.ASCII.GetBytes(string2);
string filePath = #"\Users\nico_\Documents\transfer_ex.txt";
newclient.Client.SendFile(filePath, preBuf, postBuf, TransmitFileOptions.UseDefaultWorkerThread);
}
SERVER SIDE:
private void ReceiveFile(byte[] data, int byteRead)
{
var path = #"\Users\nico_\Documents\transferreeedd_ex.txt";
FileStream fs = File.OpenWrite(path);
//Debug.WriteLine(byteRead);
//Debug.WriteLine(data);
string ddstrdata = Encoding.ASCII.GetString(data, 0, byteRead);
for (int i = 1; i < byteRead; i++)
{
Debug.WriteLine(i);
fs.WriteByte(data[i]);
}
fs.Close();
}
If you dont use any separtators, on newclient.Client.SendFile you can just put the Filepath and on Server side int i = 0 & not int i = 1

Sending and receiving files keeps hanging

my program should be able to send and receive files but for some reason whenever i click on the send (button1) and receive (button2) buttons, it keeps hanging. Not sure if its something wrong my my codes? Also, I feel like my codes are pretty long as compared to other examples i found online but I'm not sure how to rectify.
Client codes
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9000);
private void Form1_Load(object sender, EventArgs e)
{
try
{
socket.Connect(remoteEP);
textBox2.Text = "Connected to Server";
}
catch (Exception ex)
{
textBox2.Text = "Unable to connect to Server";
textBox2.Text = ex.Message;
}
}
public const string SEND = "[SEND]";
public const string RECEIVE = "[RECEIVE]";
public const string QUIT = "[QUIT]";
private void button1_Click(object sender, EventArgs e)
{
textBox1.Clear();
textBox2.Clear();
NetworkStream stream = new NetworkStream(socket);
StreamReader reader = new StreamReader(stream);
StreamWriter writer = new StreamWriter(stream);
try
{
writer.WriteLine(RECEIVE);
writer.Flush();
writer.WriteLine(textBox1.Text);
writer.Flush();
Bitmap bmp = new Bitmap(#"C:\Users\Y400\Desktop\Lectures\Year 3\WAD\Week 11" + textBox1.Text);
MemoryStream ms = new MemoryStream();
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] bmpBytes = ms.GetBuffer();
bmp.Dispose();
ms.Close();
int sent;
sent = sendData(socket, bmpBytes);
textBox1.Text = "Transferring file complete\r\n";
textBox1.Text += bmpBytes.Length + " bytes sent to Server.";
}
catch (Exception ex)
{
textBox2.Text = ex.Message;
}
}
public static int sendData (Socket s, byte[] data)
{
int total = 0;
int size = data.Length;
int left = size;
int sent;
byte[] datasize = new byte[4];
datasize = BitConverter.GetBytes(size);
sent = s.Send(datasize);
while(total<size)
{
sent = s.Send(data, total, left, SocketFlags.None);
total += sent;
left -= sent;
}
return total;
}
private void button2_Click(object sender, EventArgs e)
{
textBox2.Clear();
textBox1.Clear();
byte[] data = new byte[1024];
string fileN = textBox2.Text.Trim();
NetworkStream ns = new NetworkStream(socket);
StreamReader reader = new StreamReader(ns);
StreamWriter writer = new StreamWriter(ns);
writer.WriteLine(SEND);
writer.Flush();
writer.WriteLine(fileN);
writer.Flush();
try
{
while (true)
{
data = receiveData(socket);
MemoryStream ms = new MemoryStream(data);
break;
}
textBox2.Text = ("Receiving file from server ...\r\n" + data.Length + " bytes copied");
}
catch (Exception ex)
{
textBox2.Text = ex.Message;
}
}
public static byte[] receiveData (Socket s)
{
int total = 0;
int recv;
byte[] datasize = new byte[4];
recv = s.Receive(datasize, 0, 4, 0);
int size = BitConverter.ToInt32(datasize, 0);
int dataleft = size;
byte[] data = new byte[size];
while (total < size)
{
recv = s.Receive(data, total, dataleft, 0);
if (recv == 0)
{
break;
}
total += recv;
dataleft -= recv;
}
return data;
}
private void button3_Click(object sender, EventArgs e)
{
textBox1.Clear();
textBox2.Clear();
textBox2.Text = "Connection closed";
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
Server codes
class Program
{
public const string SEND = "[SEND]";
public const string RECV = "[RECV]";
public const string QUIT = "[QUIT]";
static void Main(string[] args)
{
runServer();
}
static void runServer()
{
try
{
byte[] data = new byte[1024];
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint localEP = new IPEndPoint(IPAddress.Any, 9000);
server.Bind(localEP);
server.Listen(10);
Console.WriteLine("Waiting for Client ...");
Socket client = server.Accept();
Console.WriteLine("Client connected");
NetworkStream stream = new NetworkStream(client);
StreamReader reader = new StreamReader(stream);
StreamWriter writer = new StreamWriter(stream);
try
{
while(true)
{
string request = reader.ReadLine();
string filename = reader.ReadLine();
if (request == QUIT)
{
Console.WriteLine("Client disconnected");
break;
}
else if (request == SEND)
{
getFileFromClient(filename, client);
}
else if (request == RECV)
{
receiveFileFromClient(filename, client);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public static void getFileFromClient(string filename, Socket client)
{
try
{
FileStream output = File.OpenWrite(filename);
Console.WriteLine(filename + " created");
int count = 0;
while(true)
{
byte[] data = new byte[1024];
int size = client.Receive(data);
output.Write(data, 0, size);
count += size;
if(size<1024)
{
break;
}
}
output.Close();
Console.WriteLine(count + " bytes read from client");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public static void receiveFileFromClient(string filename, Socket client)
{
int count = 0;
FileStream input = File.OpenRead(filename);
Console.WriteLine("Reading " + filename);
while(true)
{
byte[] data = new byte[1024];
int bytesRead = input.Read(data, 0, 1024);
client.Send(data, bytesRead, SocketFlags.None);
count += bytesRead;
if(bytesRead < 1024)
{
break;
}
}
Console.WriteLine("Transferring file completed\r\n" + count + " bytes sent to Client");
input.Close();
}
}
Generally speaking
...try to approach the problem differently.
You can't just copy paste stuff from the Internet and hope for the best. You need to understand what you're doing thoroughly.
Regarding your exact problem
Take a look at the button2_Click method.
It contains a while loop which apparently never finishes.
while (true)
{
data = receiveData(socket);
MemoryStream ms = new MemoryStream(data);
break;
}
It does finish because of the break command. But this is all very hard to read.
When you copy paste code around and then apply quick fixes you end up with a pile of code which is very hard to debug.
It took me about 10 minutes to notice the fact that the client defines it's "message verbs" like so:
public const string SEND = "[SEND]";
public const string RECEIVE = "[RECEIVE]";
public const string QUIT = "[QUIT]";
while the server defines them like so:
public const string SEND = "[SEND]";
public const string RECV = "[RECV]";
public const string QUIT = "[QUIT]";
This is maybe not the only problem, but it is sufficient to create a deadlock,
because the server never executes the positive branch of this if statement:
else if (request == RECV)
{
receiveFileFromClient(filename, client);
}
so the client believes it is about to receive something, which proves to be false.
Also make sure you send the "SEND" and "RECEIVE" message verbs when you should and not mix them up.
Good luck!
PS: I would suggest you take a look at more simpler to use techniques for sending and receiving data, such as:
WCF
ASP.NET Web Services
Web API
Ignoring any logic errors that may occur in your programs, the way you are handling things in your client whenever it is doing an action it is doing it on the GUI thread. This will make your application seem like it is locking but instead it is executing your logic on the GUI thread.
The same problem is occurring on the server. It accepts a connection, and then goes on to receive the file. It will not be able to receive any other connection until it finished receiving the file.
The server is not without problems either because it is never checking if it receives 0 bytes from the socket. Which means that the client closed its end of the connection. You are simply assuming that if you receive less than 1024 you are receiving your last part of the file. This is simply not true for TCP. You only know you received the last part if you receive 0 bytes. TCP is a byte streaming protocol you cannot assume you will be receiving blocks of 1024 bytes. It is likely that this will be in fact the case, but you should not code it like that. Check for reception of 0 bytes. On the client you did check for 0 bytes, I am puzzled why you did not do the same on the server. The problematic part is this :
byte[] data = new byte[1024];
int size = client.Receive(data);
output.Write(data, 0, size);
count += size;
if(size<1024) //you can only break if the size is 0
{
break;
}
There are probably more bugs. As the other answer also indicated some other issues.

streamread can't read any data from NetworkStream in c# ,

I have a sensor that has an ip and port 192.168.2.44:3000.
I used the herculas to connect to the device ,as you can see in the picture :
enter image description here
I need to implement this software in c# ,so i write this code :
private static void Main(string[] args)
{
try
{
byte[] buffer = new byte[2048]; // read in chunks of 2KB
int bytesRead;
var listener = new TcpListener(IPAddress.Any, 3000);
listener.Start();
NetworkStream network_stream;
StreamReader read_stream;
StreamWriter write_stream;
var client = listener.AcceptTcpClient();
network_stream = client.GetStream();
read_stream = new StreamReader(network_stream);
write_stream = new StreamWriter(network_stream);
write_stream.WriteLine("00010002000B0300010004C380");
write_stream.Flush(); //veriyi gönderiyor
string gelen;
gelen = read_stream.ReadLine();
Console.WriteLine(gelen);
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.ReadLine();
}
}
When i put a breakpoint the gelen = read_stream.ReadLine(); returns null
http://www.hw-group.com/products/hercules/index_en.html
the final code :
class Program
{
static void Main(string[] args)
{
TcpListener server = null;
try
{
Int32 port = 3000;
// IPAddress localAddr = IPAddress.Parse(IPAddress.Any);
server = new TcpListener(IPAddress.Any, port);
server.Start();
// Buffer for reading data
Byte[] bytes = new Byte[256];
String data = null;
while (true)
{
Console.Write("Waiting for a connection... ");
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("Connected!");
data = null;
NetworkStream stream = client.GetStream();
byte[] aaa = { 0, 1, 0, 2, 0, 11, 3, 0, 1, 0, 4, 195, 128 };
stream.Write(aaa, 0, aaa.Length);
int i;
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine("Received: {0}", data);
data = data.ToUpper();
byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);
stream.Write(msg, 0, msg.Length);
Console.WriteLine("Sent: {0}", data);
}
client.Close();
}
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
finally
{
server.Stop();
}
Console.WriteLine("\nHit enter to continue...");
Console.Read();
}
}

how to close tcp socket connection in c#

I have this tcp socket chat application from youtube
server side
int i;
TcpListener server = new TcpListener(IPAddress.Any, 1980);
NetworkStream stream;
TcpClient client;
byte[] datalength = new byte[4];
public Form1()
{
InitializeComponent();
}
public void ServerReceive()
{
stream = client.GetStream();
new Thread(() =>
{
while ((i = stream.Read(datalength, 0, 4)) != 0)
{
byte[] data = new byte[BitConverter.ToInt32(datalength, 0)];
stream.Read(data, 0, data.Length);
this.Invoke((MethodInvoker)delegate
{
txtLog.Text += System.Environment.NewLine + "Client : " + Encoding.Default.GetString(data);
});
}
}).Start();
}
public void ServerSend(string msg)
{
stream = client.GetStream();
byte[] data;
data = Encoding.Default.GetBytes(msg);
int length = data.Length;
byte[] datalength = new byte[4];
datalength = BitConverter.GetBytes(length);
stream.Write(datalength, 0, 4);
stream.Write(data, 0, data.Length);
}
private void btnSend_Click(object sender, EventArgs e)
{
try
{
if (client.Connected)
{
ServerSend(txtSend.Text);
}
}catch
{
txtLog.Text += "connection close";
}
}
private void btnListen_Click(object sender, EventArgs e)
{
server.Start();
new Thread(() =>
{
client = server.AcceptTcpClient();
if (client.Connected)
{
ServerReceive();
}
}).Start();
}
client side
int i;
TcpClient client;
NetworkStream stream;
byte[] datalength = new byte[4];
public Form1()
{
InitializeComponent();
}
public void ClientReceive()
{
stream = client.GetStream();
new Thread(() =>
{
while ((i = stream.Read(datalength, 0, 4)) != 0)
{
byte[] data = new byte[BitConverter.ToInt32(datalength, 0)];
stream.Read(data, 0, data.Length);
this.Invoke((MethodInvoker)delegate
{
txtLog.Text += System.Environment.NewLine + "Server : " + Encoding.Default.GetString(data);
});
}
}).Start();
}
public void ClientSend(string msg)
{
stream = client.GetStream();
byte[] data;
data = Encoding.Default.GetBytes(msg);
int length = data.Length;
byte[] datalength = new byte[4];
datalength = BitConverter.GetBytes(length);
stream.Write(datalength, 0, 4);
try
{
stream.Write(data, 0, data.Length);
}
catch
{
stream.Dispose();
client.Close();
}
}
private void btnConnect_Click(object sender, EventArgs e)
{
try
{
client = new TcpClient("127.0.0.1", 1980);
ClientReceive();
txtLog.Text += Environment.NewLine+ "Connected";
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void btnSend_Click(object sender, EventArgs e)
{
if (client.Connected)
{
ClientSend(txtSend.Text);
}
}
now, all of these works fine for me, however everytime i close one them i get this error
'Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.' at ClientReceive() or ServerReceive()
how should i catch this error if one of them suddenly closed or the network cable suddenly unplug? thanks in advance
In this case, you're receiving a System.IO.IOException from the NetworkStream object. This exception has a nested System.Net.Sockets.SocketException with an ErrorCode of 10054 (SocketErrorCode == ConnectionReset). To handle the exception, use a try-catch block. For example,
using System;
using System.IO;
using System.Net.Sockets;
stream = client.GetStream();
new Thread(() =>
{
try
{
while ((i = stream.Read(datalength, 0, 4)) != 0)
{
byte[] data = new byte[BitConverter.ToInt32(datalength, 0)];
stream.Read(data, 0, data.Length);
this.Invoke((MethodInvoker)delegate
{
txtLog.Text += System.Environment.NewLine + "Server : " + Encoding.Default.GetString(data);
});
}
}
catch (IOException ioex)
{
if (ioex.InnerException != null)
{
var sex = ex.InnerException as SocketException;
if (sex == null)
{
txtLog.Text += Environment.NewLine + "An unknown exception occurred.";
}
else
{
switch (sex.SocketErrorCode)
{
case SocketError.ConnectionReset:
txtLog.Text += Environment.NewLine + "A ConnectionReset SocketException occurred."
break;
default:
txtLog.Text += Environment.NewLine + "A SocketException occurred.";
break;
}
}
}
else
{
txtLog.Text += Environment.NewLine + "An IOException occurred.";
}
}
}).Start();

Delay 3mins at the start of the program why? socket programming in C#

I will get 3mins of delay at the start of the below program.but where as in hyper terminal it shows every data for every 2 secs.
Her is my below code.please let me know where i went wrong .How i can rectify this delay. any suggestion?
private void StartReceiving()
{
// coding part of receiving changed.
try
{
string IPStr = textBox1_IPaddress.Text.Trim();
string portStr = textBox2_Port.Text.Trim();
int port = Convert.ToInt32(portStr);
int bytesRead = 0;
byte[] buffer = new byte[9];
//------------------------------------------------------------------
IPAddress ipAddress = System.Net.IPAddress.Parse(IPStr);
//create server's tcp listener for incoming connection
try
{
textBox3.Visible = true;
client = new TcpClient();
client.Connect(IPStr, port);
ns = client.GetStream();
while (true)
{
if (ns.DataAvailable)
{
byte[] data = ReadNumberBytes(ns, 9);
ASCIIEncoding encoder = new ASCIIEncoding();
msg = encoder.GetString(data);
textBox3.AppendText(msg);
textBox3.AppendText("\n");
GetData(msg);
}
else
{
Thread.Sleep(4000);
byte[] data = ReadNumberBytes(ns, 9);
ASCIIEncoding encoder = new ASCIIEncoding();
msg = encoder.GetString(data);
GetData(msg);
}
}
client.Close();
}
catch (SocketException se)
{
//message box;
}
}
}
public static byte[] ReadNumberBytes(NetworkStream stream, int n)
{
byte[] buffer = new byte[n];
int bytesRead = 0;
int chunk;
while (bytesRead < n)
{
chunk = stream.Read(buffer, (int)bytesRead, buffer.Length - int)bytesRead);
if (chunk == 0)
{
// error out.
throw new Exception("Unexpected disconnect");
}
bytesRead += chunk;
}
return buffer;
}

Categories