Writing/reading string through NetworkStream (sockets) for a chat

user43132 picture user43132 · Sep 27, 2014 · Viewed 24.2k times · Source

Sorry if this is hard to understand, trying out C# for the first time.

I am trying to make a simple public 'chat' between clients that are connected to the server. I've tried passing integers to the server and printing them out and everything was fine, however,when I switched to strings, it seems that it can only pass 1 character (because of ns.Write(converted, 0, 1);). If I increase the ns.Write to ns.Write(converted,0,10) everything crashes (both the client and the server) when I enter a message that is less than 10 characters.

Server code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Net.Sockets;


namespace MultiServeris
{
    class Multiserveris
    {
        static void Main(string[] args)
        {
            TcpListener ServerSocket = new TcpListener(1000);         
            ServerSocket.Start();                                     
            Console.WriteLine("Server started");
            while (true)
            {
                TcpClient clientSocket = ServerSocket.AcceptTcpClient();        
                handleClient client = new handleClient();                       
                client.startClient(clientSocket);
            }
        }
    }

    public class handleClient
    {
        TcpClient clientSocket;
        public void startClient(TcpClient inClientSocket)
        {
            this.clientSocket = inClientSocket;
            Thread ctThread = new Thread(Chat);
            ctThread.Start();
        }
        private void Chat()
        {
            byte[] buffer = new byte[10]; 
            while (true)
            {
                NetworkStream ns = clientSocket.GetStream();
                ns.Read(buffer,0,1);
                string line = Encoding.UTF8.GetString(buffer);
                Console.WriteLine(line);
            }
        }
    }
}

Client code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;

namespace Klientas
{
    class Klientas
    {
        static void Main(string[] args)
        {
            while (true)
            {
                TcpClient clientSocket = new TcpClient("localhost", 1000);
                NetworkStream ns = clientSocket.GetStream();
                byte[] buffer = new byte[10];
                string str = Console.ReadLine();
                byte[] converted = System.Text.Encoding.UTF8.GetBytes(str);
                ns.Write(converted, 0, 1);
            }
        }
    }
}

Answer

tyranid picture tyranid · Sep 28, 2014

You're best using the BinaryReader/BinaryWriter classes to correctly format and read out data. This removes the need to process it yourself. For example in the client do:

BinaryWriter writer = new BinaryWriter(clientSocket.GetStream());
writer.Write(str);

And in the server:

BinaryReader reader = new BinaryReader(clientSocket.GetStream());
Console.WriteLine(reader.ReadString());