comparing values sent to/from server by NetworkStream - c#

When u know why the sent string "kamote" to server and the string received "kamote" from server are not the same..
CLIENT
tcpClient = new TcpClient();
tcpClient.Connect(ServerIP, Port);
connectionState = (HandShake("kamote", tcpClient)) ? "Connected to " + ServerIP.ToString() : "Host unreachable.";
private bool HandShake(String str, TcpClient tcpClient)
{
using (NetworkStream ns = tcpClient.GetStream())
{
byte[] toServer = Encoding.ASCII.GetBytes(str);
ns.Write(toServer,0,toServer.Length);
ns.Flush();
byte[] fromServer = new byte[10025];
ns.Read(fromServer, 0, (int)tcpClient.ReceiveBufferSize);
return Encoding.ASCII.GetString(fromServer).Equals(str);
}
}
SERVER
TcpClient tcpClient = new TcpClient();
tcpClient = tcpListener.AcceptTcpClient();
NetworkStream ns = tcpClient.GetStream();
byte[] fromClient = new byte[10025];
ns.Read(fromClient, 0, (int)tcpClient.ReceiveBufferSize);
byte[] toClient = fromClient;
ns.Write(toClient, 0, toClient.Length);
ns.Flush();
Client sent "kamote"
Server received "kamote"
Server sent "kamote"
Client received "kamote"
HandShake() always returns false. How can I fix this?

As in the previous question you asked, you're not keeping track of the number of bytes you received. So what's happening is this:
On the client, you send the string "kamote".
On the server, it receives that string into a buffer that's 10025 bytes long.
The server then sends the entire buffer back to the client -- all 10025 bytes
The client receives all or part of those 10025 bytes and converts them to a string.
The string that gets converted is really "kamote" with a bunch of 0's after it.
You must use the return value from Read to know how many bytes you received.

Did you try limiting the string length to the actual read bytes like this:
noOfBytes = ns.Read(bytes, 0, ...);
Encoding.ASCII.GetString(bytes, 0, noOfBytes);

You are including a lot of 0 characters, since you are including the entire fromServer in getstring. 0s don't print, but they are there. You must tell it the correct number of bytes to decode.

Related

Framing bytes (Begining and End) to be added inside the TCP/IP protocol on the client request

I am writing TCP/IP Client using C# - System.Net.Sockets to call the Interface created in the TCP/IP Socket on the 'X' Server.
Message body text format - 20 digits(ASCII format)
All messages text will be framed with below format,
Framing bytes - 2 digit Hexadecimal values
Needs to be add in the starting and ending fields
It needs to be in the TCP/IP protocol and not within the body of the message.
Question: How do I add hexadecimal framing bytes in the TCP/IP protocol and not within the body of message.
Here is my code snippet -
public static void Connect()
{
// 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 = 1234;
String server = "serverip";
String message = "12345678901234567890"
TcpClient client = new TcpClient(server, port);
// Translate the passed message into ASCII and store it as a Byte array.
Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
// 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);
Console.WriteLine("Sent: {0}", message);
// Receive the TcpServer.response.
// Buffer to store the response bytes.
data = new Byte[256];
// String to store the response ASCII representation.
String responseData = String.Empty;
// Read the first batch of the TcpServer response bytes.
Int32 bytes = stream.Read(data, 0, data.Length);
responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
Console.WriteLine("Received: {0}", responseData);
// Close everything.
stream.Close();
client.Close();
Console.WriteLine("\n Press Enter to continue...");
Console.Read();
}
Framing bytes (you dont say what they contain, it looks like you are quoting from a spec) seem to be needed to be added before and after the message, just send them. Assumed that the before bytes are 0x1234
var pre = new Byte[2];
pre[0] = 0x12;
pre[1] = 0x34;
stream.Write(pre, 0, 2);
then after the body of the message send the trailer the same way

Unable to retrieve message from TCP/IP server C# console app

I have to create a TCP/IP client against a existing server (which has a specific documentation), I followed same but still no response getting from server.
Initially it was the problem of Message format and SMTP Commands, which i replaced from another working command.
I have to use SSL without client certificate for login.
TcpClient client = new TcpClient("Server DNS", PORT);
Console.WriteLine("-------------------------- \nConnection is : " + client.Connected);
SslStream stream = new SslStream(client.GetStream(), false, VerifyServerCertificate, null);
stream.AuthenticateAsClient("Server DNS");
Console.Write("Authentication status :" + stream.IsAuthenticated);
// FOR NOW I AM ONLY SENDING LOGIN COMMAND
string line = "BDAT 30 LAST<EOL>{login command}<LF>useridpassword";
stream.Write(Encoding.UTF8.GetBytes(line));
stream.Flush();
string serverMessage = ReadMessage(stream);
Console.WriteLine("\nServer says: {0}", serverMessage);
stream.Close();
This sends the command but return message is always empty.
here is method i am using for ReadMessage.
static string ReadMessage(SslStream sslStream)
{
// Read the message sent by the client.
// The client signals the end of the message using the
// "<EOF>" marker.
byte[] buffer = new byte[2048];
StringBuilder messageData = new StringBuilder();
int bytes = -1;
sslStream.ReadTimeout = 60000;
do
{
// Read the client's test message.
bytes = sslStream.Read(buffer, 0, buffer.Length);
sslStream.Flush();
// Use Decoder class to convert from bytes to UTF8
// in case a character spans two buffers.
Decoder decoder = Encoding.UTF8.GetDecoder();
char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)];
decoder.GetChars(buffer, 0, bytes, chars, 0);
messageData.Append(chars);
// Check for EOF or an empty message.
if (messageData.ToString().IndexOf("<EOF>") != -1)
{
break;
}
} while (bytes != 0);
return messageData.ToString();
}
Below is the screenshot for same code
console error
I am also getting this error when use break points
Sorry for this long post but i think these info was necessary.
Please any help is appreciated .. Its very frustrating situation as i couldn't proceed since last 8 days bcz of it.
Thank you.

C# - Seems to be receiving two TCP packets at once?

I'm making a chatroom application, and I send TCP packets to communicate between the server and the client.
I have the following code:
string returnMessage = "[EVT]USERSUCCESS";
bytes = Encoding.ASCII.GetBytes(returnMessage);
info.WriteToStream(bytes);
foreach (ConnectionInfo con in connections)
{
info.WriteToStream(bytes);
bytes = Encoding.ASCII.GetBytes("[EVT]USERJOIN;" + username);
con.WriteToStream(bytes);
}
However, when the client reads this, the response is:
[EVT]USERSUCCESS[EVT]USERJOIN;Name
Which seems as though it is receiving both packets at once..?
This is the code I have for receiving:
static void ServerListener()
{
while (true)
{
byte[] bytes = new byte[1024];
int numBytes = stream.Read(bytes, 0, bytes.Length);
string message = Encoding.ASCII.GetString(bytes, 0, numBytes);
if (HandleResponse(message) && !WindowHasFocus())
{
player.Play();
}
}
}
Which is run as a separate thread. HandleResponse() is fully working.
Thanks in advance!
Tcp is a stream protocol not a packet protocol.
You could get the bytes in mutiple packets or a single packet like you are doing.
What you need to do is put a byte that siginifies the end of a packet (such as the null byte)
Psudeo code:
Have a buffer that you add every byte received to.
If their is a null byte in the buffer then split the buffer at the null byte
Handle the left side as a complete packet. Keep the right side in the buffer until you get a new null byte.
Advanced TCP:
You may want to add your own error checking in your "packet"

Socket writing not working properly c#

I'm working on a biometry system with my C# application.
Sdk provices a connection via TCP/IP on port 2100, and works by receiving and sending strings to communicate .
My class:
class Biometry
{
private System.Net.Sockets.TcpClient _clientSocket = new System.Net.Sockets.TcpClient();
public Biometry() {
//connect to socket
_clientSocket.Connect("127.0.0.1", 2100);
_clientSocket.ReceiveTimeout = 9000;
}
public String identify(String msg) {
//get network stream
NetworkStream _serverStream = _clientSocket.GetStream();
//send an array of bites that represents a string(encoded)
System.Text.ASCIIEncoding ASCII = new System.Text.ASCIIEncoding();
byte[] outStream = System.Text.Encoding.ASCII.GetBytes(msg);
_serverStream.Write(outStream, 0, outStream.Length);
//reads the response from networkStream
byte[] inStream = new byte[10025];
_serverStream.Read(inStream, 0, (int)_clientSocket.ReceiveBufferSize);
string returndata = System.Text.Encoding.ASCII.GetString(inStream);
_serverStream.Close();
return returndata;
}
}
The problem is:
It is not working!! The biometry only works(SDK only understand my request) when I close the application(connection is closed).
You might need to flush the stream before your start reading using _serverStream.Flush().
Another problem might be that in your question you say you need to connect to port 21000, but in your code you connect to 2100, which might be a typo in either place, but should be fixed ;-)
In addition to flushing the stream, your server might also be waiting for an "end of message" indicator?

How to send length of a package via tcp/ip protocol

I'm doing this for one of my school projects. I'm trying to design a multi-threaded server that accepts clients for working with a database (adding, deleting records etc). When I connect the client to the server I want to receive all the students in my database.
I access the database on the Server Side and store the information in an ArrayList, which I'm trying to send it over the network. I don't have any knowledge on XMLserializing so I'm trying to send each string in the arrayList to the client. When I send the data from the server, I sometimes receive all the data in the same time, sometimes I don't, so my first guess was that I have to split the data I send into packages of some length. I don't see how can I add the length at the beginning of a package. Wouldn't it be the same thing? Maybe I get the correct length maybe I don't.
Here is my code; I didn't try sending the length of each package yet, because I have no idea how. I tried sending from the server the length of the arraylist, and read from the network stream that many times, but it doesn't work ( I receive all data in one package).
Server side:
private void HandleClient(object client)
{
try
{
ClientNo++;
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
byte[] bytes = new byte[4096];
int i;
// Robot r = new Robot();
Protocol p = new Protocol();
ArrayList ListaStudentiResponse = p.ExecuteQueryOnStudents("select * from studenti");
byte[] Length = new byte[4];
Length = System.Text.Encoding.ASCII.GetBytes(ListaStudentiResponse.Count.ToString());
clientStream.Write(Length, 0, Length.Length);
foreach ( String s in ListaStudentiResponse)
{
byte[] data = System.Text.Encoding.ASCII.GetBytes(s);
clientStream.Write(data, 0, data.Length);
}
tcpClient.Close();
ClientNo--;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
On Client:
private void connectToServerToolStripMenuItem_Click(object sender, EventArgs e)
{
tcpclient = new TcpClient();
NetworkStream netStream;
try
{
tcpclient.Connect("localhost", 8181);
netStream = tcpclient.GetStream();
Byte[] bytes = new Byte[10000];
int readBytes = netStream.Read(bytes, 0, bytes.Length);
int Length =Int32.Parse(Encoding.ASCII.GetString(bytes, 0, readBytes));
MessageBox.Show(Length.ToString());
int i = 0;
while (i < Length)
{
i++;
Byte[] b = new Byte[10000];
readBytes = netStream.Read(bytes, 0, bytes.Length);
String response = Encoding.ASCII.GetString(b, 0, readBytes);
MessageBox.Show(response);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
You can use a StateObject to keep track of how large your data is, and then test during ReadCallback to see if you have "all" of the message. If you don't have all of your message, you call BeginRecieve again with the current StateObject.
Here is a decent example: http://www.csharphelp.com/2007/02/asynchronous-server-socket-using-c/
This is what I been using:
How to use the buffer on SocketAsyncEventArgs object
Look at the accepted answer. 1st off, this is using something call completion port which is highly efficient than async. Secondly, I find that it is very easy to troubleshoot by looking at e.SocketError to find out the exact cause for failure.
How it works is that for your message to send, append the message with a header and trailer.
So when it receive the message, it will check if the trailer is received. If trailer not received, it will continue receive for that client, and append the received message to the stringBuilder object. Once the trailer is received, just call stringbuilder.toString() to get the whole content.

Categories

Resources