I have a switch statement that uses a string converted from a char[] that was sent over a data stream from a server to the client. The code is client-side.
The default case is always hit even though the server and the default error code is always matching cases exactly.
SERVER SIDE
private void SendToClient(string message, TcpAccount account)
{
try
{
byte[] buffMessage = Encoding.ASCII.GetBytes(message);
account.TcpClient.GetStream().WriteAsync(buffMessage, 0, buffMessage.Length);
log.AppendText(string.Format("Message {0} sent to account {1}", message, account.ID));
log.AppendText(Environment.NewLine);
}
catch
{
log.AppendText(string.Format("Message {0} sent to account {1}", message, account.ID));
log.AppendText(Environment.NewLine);
}
}
CLIENT SIDE
public async void ReadDataAsync(TcpClient client)
{
try
{
StreamReader clientStreamReader = new StreamReader(client.GetStream());
char[] buff = new char[64];
int readByteCount = 0;
while (true)
{
readByteCount = await clientStreamReader.ReadAsync(buff, 0, buff.Length);
if (readByteCount <= 0)
{
Console.WriteLine("Disconnected from server.");
client.Close();
break;
}
string code = new string(buff);
ProcessServerCode(code);
Array.Clear(buff, 0, buff.Length);
}
}
catch
{
}
}
public void ProcessServerCode(string code)
{
switch (code)
{
case "regcom":
MessageBox.Show("Registration Complete");
break;
case "logcom":
MessageBox.Show("Login Complete");
break;
case "badpass":
MessageBox.Show("Invalid Password");
break;
case "badaccount":
MessageBox.Show("Invalid Account");
break;
default:
MessageBox.Show("Unknown Code: " + code);
break;
}
}
I can't get it off the default code.
Also, since I'm new to client/server and socket programming, I just realized the server sends a byte[] but the client receives a char[]. Is there any conflict there? Any particular reason for this (since I'm using those particular pieces of code from an online training session)?
The first problem I see is that you're ignoring readByteCount
(which is actually a character count, not a byte count); you should use:
string code = new string(buff, 0, readByteCount);
However, the next problem I see is that you don't have any framing protocol. This means:
In either case:
as in either case, it'll never be possible to recover the position correctly. Hence: frames, where each frame is a complete message.
A common approach with text-based protocols is to use a newline as a frame (I'll let you decide whether that means CR, LF, CRLF, etc); then you can just use ReadLine
/ ReadLineAsync
on the text reader, and it'll do it all automatically, so:
string code = await clientStreamReader.ReadLineAsync();
if (code is null)
{
Console.WriteLine("Disconnected from server.");
client.Close();
}
else
{
ProcessServerCode(code);
}