I’m sending data between a server and a client using TCP. I send a stream of bytes, so I convert the strings to byte arrays, send to the client, then convert it back to a string. Then I insert this string into a multiline textbox with Environment.NewLine after each one. However, a new line isn’t appearing.
I’ve tried multiple ways of converting the string to arrays and back to strings all with the same result. Environment.NewLine doesn’t work. \n\r doesn’t work.
I’ve tried converting using the following techniques:
Encoding.ASCII.GetString()andEncoding.ASCII.GetBytes()Encoding.Unicode.GetString()andEncoding.Unicode.GetBytes()-
I’ve also used the code on the following website which uses:
System.Text.UTF8Encoding encoding=new System.Text.UTF8Encoding();
String to Byte Array Conversion in C# and VB.NET (and back)
How should I convert these strings back and forth to get this to work? My client is currently C# but is going to be java in production.
EDIT:
AttachMessage(ByteArrayToStr(messageInByteArray)); // Doesn't work
AttachMessage("TEST"); // works
public void AttachMessage(string data)
{
textBox2.Text += data + Environment.NewLine;
}
public static string ByteArrayToStr(byte[] arr)
{
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
return encoding.GetString(arr);
}
public static byte[] StrToByteArray(string str)
{
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
return encoding.GetBytes(str);
}
It is a conversion issue because it works with non-converted strings.
EDIT 2:
public partial class Form1 : Form
{
public volatile List<TcpClient> connectedClients;
public volatile bool ServerOn;
public volatile TcpListener server;
public delegate void txtBoxDelegate(string data);
public delegate void tcpCommand(string ipAddress);
public delegate void chatMessageDelegate(byte[] message);
public Form1()
{
InitializeComponent();
connectedClients = new List<TcpClient>();
ServerOn = false;
server = new TcpListener(System.Net.IPAddress.Parse("127.0.0.1"), 6789);
}
private void button1_Click(object sender, EventArgs e)
{
if (!ServerOn)
{
Thread serverThread = new Thread(new ThreadStart(TcpServer));
serverThread.IsBackground = true;
serverThread.Start();
lblServerStatus.Text = "The server is On.";
lblServerStatus.ForeColor = Color.Green;
lstServerUpdates.Text = String.Empty;
button1.Text = "Turn server Off";
ServerOn = true;
}
else
{
ServerOn = false;
lstServerUpdates.Text = "Server has been turned off.";
lblServerStatus.Text = "The server is Off.";
lblServerStatus.ForeColor = Color.Red;
}
}
public static string ByteArrayToStr(byte[] arr)
{
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
return encoding.GetString(arr);
}
public static byte[] StrToByteArray(string str)
{
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
return encoding.GetBytes(str);
}
private void TcpServer()
{
printToTextBox("Starting TCP Server.");
server.Start();
while (ServerOn)
{
if (!server.Pending())
{
Thread.Sleep(10);
continue;
}
TcpClient clientSocket = server.AcceptTcpClient();
NetworkStream stream = clientSocket.GetStream();
connectedClients.Add(clientSocket);
Thread clientThread = new Thread(new ParameterizedThreadStart(ClientThreads));
clientThread.Start(clientSocket);
byte[] bytes = StrToByteArray("Successfully connected to the server.");
stream.Write(bytes, 0, bytes.Length);
printToTextBox("Client successfully connected to server.");
}
server.Stop();
}
public void ClientThreads(object tcpClient)
{
TcpClient clientSocket = (TcpClient)tcpClient;
NetworkStream clientStream = clientSocket.GetStream();
byte[] clientMessage = new byte[100];
while (ServerOn)
{
clientStream.Read(clientMessage, 0, clientMessage.Length);
string message = ByteArrayToStr(clientMessage);
if (message.Contains("!chat"))
{
SendChatMessage(StrToByteArray(message.Substring(5) + Environment.NewLine));
}
else if (message.Contains("!start"))
{
StartWebcam(((IPEndPoint)clientSocket.Client.RemoteEndPoint).Address.ToString());
}
else if (message.Contains("!stop"))
{
StopWebcam(((IPEndPoint)clientSocket.Client.RemoteEndPoint).Address.ToString());
}
}
clientSocket.Close();
connectedClients.Clear();
}
public void printToTextBox(string data)
{
if (this.InvokeRequired)
{
this.BeginInvoke(new txtBoxDelegate(printToTextBox), data);
return;
}
lstServerUpdates.Text += data + Environment.NewLine;
}
public void SendChatMessage(byte[] message)
{
foreach (TcpClient client in connectedClients)
{
NetworkStream stream = client.GetStream();
stream.Write(message, 0, message.Length);
printToTextBox(ByteArrayToStr(message));
}
}
public void StartWebcam(string IPAddress)
{
if (this.InvokeRequired)
{
this.BeginInvoke(new tcpCommand(StartWebcam), IPAddress);
return;
}
//code to stop webcam for the specified client
printToTextBox("Starting webcam for IP: " + IPAddress);
}
public void StopWebcam(string IPAddress)
{
if (this.InvokeRequired)
{
this.BeginInvoke(new tcpCommand(StopWebcam), IPAddress);
return;
}
//code to stop webcam for specified client
printToTextBox("Stopping webcam for IP: " + IPAddress);
}
}
That’s correct, TCP is a stream. Which doesn’t support anything like a “packet”. Like a line of text. There’s no obvious way to convert a stream to byte[], other than to receive everything until the client closes the connection. Which of course means that you’ll display everything, followed by a single Environment.NewLine.
Rethink your approach. Like actually sending the line-endings in the data as well so you don’t have to add them in the receiver. Artificially creating packets by first sending 4 bytes that encodes the packet length is another approach.