i have a bare bones chat client in console. Here’s the code
For server
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
namespace chat_server
{
class Program
{
static TcpListener server = new TcpListener(IPAddress.Any, 9999);
static void input(object obs)
{
StreamWriter writer = obs as StreamWriter;
string op = "nothing";
while (!op.Equals("exit"))
{
Console.ResetColor();
Console.WriteLine("This is the " + Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("Enter your text(type exit to quit)");
op = Console.ReadLine();
writer.WriteLine(op);
writer.Flush();
}
}
static void output(Object obs)
{
StreamReader reader = obs as StreamReader;
Console.ForegroundColor = ConsoleColor.Green;
while (true)
{
Console.WriteLine(reader.ReadLine());
}
}
static void monitor()
{
while (true)
{
TcpClient cls = server.AcceptTcpClient();
Thread th = new Thread(new ParameterizedThreadStart(mul_stream));
th.Start(cls);
}
}
static void mul_stream(Object ob)
{
TcpClient client = ob as TcpClient;
Stream streams = client.GetStream();
StreamReader reads = new StreamReader(streams);
StreamWriter writs = new StreamWriter(streams);
new Thread(new ParameterizedThreadStart(output)).Start(reads);
input(writs);
}
static void Main(string[] args)
{
server.Start();
monitor();
server.Stop();
Console.ReadKey();
}
}
}
and here’s the client code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
namespace chat_client
{
class Program
{
static StreamReader reader;
static StreamWriter writer;
static Thread input_thread;
static void input()
{
string op = "nothing";
while (!op.Equals("exit"))
{
Console.ResetColor();
Console.WriteLine("Enter your text(type exit to quit)");
op = Console.ReadLine();
writer.WriteLine(op);
writer.Flush();
}
}
static void output()
{
Console.ForegroundColor = ConsoleColor.Blue;
while (true)
{
Console.WriteLine(reader.ReadLine());
}
}
static void Main(string[] args)
{
Console.WriteLine("Enter the ip address");
string ip = Console.ReadLine();
TcpClient client = new TcpClient(ip,9999);
NetworkStream stream = client.GetStream();
reader = new StreamReader(stream);
writer = new StreamWriter(stream);
input_thread = new Thread(input);
input_thread.Start();
/*
writer.Write("Hello world");
writer.Flush();
Console.WriteLine("Message Sent");*/
output();
client.Close();
Console.ReadKey();
}
}
}
Now the thing is that i am having some issues converting this code to GUI. For instance the input function in the server which delivers the message through a specific stream to a client should be somewhat equivalent to SEND button in GUI.
However each thread creates its own stream and i don’t think that creating seprate event handlers on different threads would be a good idea.
In short i need some advice on where to start with this project.
Thank you.
Networking is hard. Your current approach, which is just reading everything and treating everything as complete messages, is fragile. It works during debugging but will fail during production since TCP is stream based.
Instead, you could use an existing framework to abstract away the networking layer. As it happens, I’ve made a framework which is open source (LGPL).
In this case we’ll just want to be able to chat. So I added a chat message definition like this:
That message is put in a shared assembly (used both by the client and the server).
The server itself is defined like this:
See? No networking code anywhere.
The client is event easier:
The full example is available here: https://github.com/jgauffin/Samples/tree/master/Griffin.Networking/ChatServerClient
Update:
Since it’s a school project and you can’t use anything other than .NET I would probably use the easiest possible approach. And that’s to use new line (
"\r\n") as delimiter.so in each side you just used
var chatMessage = streamReader.ReadLine()andstreamWriter.WriteLine("Chat message");