I have an array where the number of elements are randomly generated between 1-11 and the values are also randomly generated from 0 to 254.
I would like to send these values from the client to the server and write out the original array values with Console.WriteLine()
. I've been trying for days and I tried a lot of options but I couldn't solve this problem. I share the code which I think was the closest but the server sent an error like this:
“The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or a non-white space character among the padding characters”
After that I tried to replace ("-","+") to ("_","/") but it didn't work.
The program of the client is:
static void Main(string[] args)
{
Random rnd = new Random();
byte[] array = new byte[rnd.Next(1, 11)];
for (int i = 0; i < array.Length; ++i)
{
array[i] = (byte)rnd.Next(255);
Console.WriteLine(array[i]);
}
System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient();
clientSocket.Connect("111.11.11.111", 8888);
while (true)
{
NetworkStream serverStream = clientSocket.GetStream();
string str = Convert.ToBase64String(array);
byte[] outStream = System.Text.Encoding.UTF8.GetBytes(str);
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
}
}
The program of the server is:
IPAddress ipAd = IPAddress.Parse("111.11.11.111");
TcpListener serverSocket = new TcpListener(ipAd, 8888);
TcpClient clientSocket = default(TcpClient);
serverSocket.Start();
Console.WriteLine("*****Server started*****");
clientSocket = serverSocket.AcceptTcpClient();
Console.WriteLine("Accepted connection from client");
while(true)
{
try
{
NetworkStream networkStream = clientSocket.GetStream();
byte[] bytesFrom = new byte[10025];
if(networkStream.DataAvailable)
{
networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);
string dataFromClient = System.Text.Encoding.UTF8.GetString(bytesFrom);
byte[] decByte = Convert.FromBase64String(dataFromClient);
foreach (var item in decByte)
{
Console.WriteLine(item.ToString());
}
networkStream.Flush();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
This codes work perfectly in the same console app but probably it's not working between the client and the server:
string str = Convert.ToBase64String(array);
Console.WriteLine(str);
byte[] decByte = Convert.FromBase64String(str);
Console.WriteLine(decByte[0]);
I might overcomplicated the whole thing but I got so confused at the end. Do I even need to encode if I already have a byte array? Could someone please show me the easiest way or ways how can it be done? Thanking you in advance for your time and assistance.
The first problem I noticed is that in your server code, you've called UTF8.GetString
using the entire buffer instead of specifying the number of bytes that you actually received. Change this:
networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);
string dataFromClient = System.Text.Encoding.UTF8.GetString(bytesFrom);
Into this:
var receivedCount = networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);
string dataFromClient = System.Text.Encoding.UTF8.GetString(bytesFrom, 0, receivedCount);
You will eventually run into another problem, however, as messages sometimes get fragmented and your design doesn't include any method for signaling that the entire message has been received or not. You'll need to put a line break at the end of the each message, or prefix the messages with the total expected size, or something so that the server knows when all the data has been received. You can't expect everything to arrive in one piece.