I’m trying to send a couple of data via Sockets, so it’s converted to bytes and then back to String on the Server. But I can only do one apparently.
Server code:
static void Read(IAsyncResult ar)
{
int fileNameLen = 1;
//int userNameLen = 9;
State newState = (State)ar.AsyncState; //gets state of Socket
Socket handler = newState.Socket_w; //passes Socket to handler
int bytesRead = handler.EndReceive(ar); //terminates Data Receive from Socket.
if (bytesRead > 0)
{
if (flag == 0)
{
fileNameLen = BitConverter.ToInt32(newState.buffer, 0); //gets filename length
fileName = Encoding.UTF8.GetString(newState.buffer, 4, fileNameLen); //gets filename
//userNameLen = BitConverter.ToInt32(newState.buffer, 8);
//getUsername = Encoding.UTF8.GetString(newState.buffer, 8, fileNameLen);
flag++;
}
}
}
Client code:
internal static void uploadFile(string host, string username, string getGame, string filename, string filepath)
{
byte[] m_clientData;
Socket clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
byte[] fileName = Encoding.UTF8.GetBytes(username + "_" + filename);
byte[] fileData = File.ReadAllBytes(filepath);
byte[] fileNameLen = BitConverter.GetBytes(fileName.Length);
//byte[] sendUsername = Encoding.UTF8.GetBytes(username);
//byte[] sendUsernameLen = BitConverter.GetBytes(sendUsername.Length);
//byte[] sendGame = Encoding.UTF8.GetBytes(getGame);
//byte[] sendGameLen = BitConverter.GetBytes(sendGame.Length);
m_clientData = new byte[4 + fileName.Length + fileData.Length];
fileNameLen.CopyTo(m_clientData, 0);
fileName.CopyTo(m_clientData, 4);
fileData.CopyTo(m_clientData, 4 + fileName.Length);
//sendUsernameLen.CopyTo(m_clientData, 0);
//sendUsername.CopyTo(m_clientData, 4);
//sendGameLen.CopyTo(m_clientData, 0);
//sendGame.CopyTo(m_clientData, 4);
clientSock.Connect(host, 8889);
clientSock.Send(m_clientData); //tofix exception
clientSock.Close();
}
I can’t seem to decrypt it properly over on Server. Can anyone help me with the buffersizes and whatnot?
Readdoes not know anything about what was sent; TCP is basically just a stream – so there is absolutely nothing to say that you have all the data in one call toRead; you could have:You need to devise some kind of framing protocol that lets the receiver know when they have an entire message. That could be as simple as a length prefix, or can be more complex. You should then buffer the data in memory (or process it gradually) until you have the entire message. One call to
Readis very unlikely to represent a single and complete message. Indeed, this is guaranteed not to be the case if a message is larger than yournewstate.buffer, but you can get the same result even for small messages and a large buffer.