public class MessageSender : IMessageSender
{
TcpClient client;
Stream streamToServer;
public bool Connect(IPAddress ip, int port)
{
try { client = new TcpClient(); client.Connect(ip, port); streamToServer = client.GetStream(); return true; }
catch { return false; }
}
public bool SendMessage(Message msg)
{
try { lock (streamToServer) { byte[] buf = Encoding.Unicode.GetBytes(msg.ToString()); streamToServer.Write(buf, 0, buf.Length); return true; } }
catch { return false; }
}
public void SignOut()
{
streamToServer?.Dispose();
client?.Close();
}
}
public delegate void PortNumberReadyEventHandler(int port);
public class MessageReceiver : IMessageReceiver
{
public event MessageReceivedEventHandler MessageReceived;
public event ConnectionLostEventHandler ClientLost;
public event ClientConnectedEventHandler ClientConnected;
public event PortNumberReadyEventHandler PortNumberReady;
Thread workerThread;
TcpListener listener;
public MessageReceiver() { ((IMessageReceiver)this).StartListen(); }
void IMessageReceiver.StartListen()
{
workerThread = new Thread(ListenThreadMethod) { IsBackground = true };
workerThread.Start();
}
private void ListenThreadMethod()
{
listener = new TcpListener(IPAddress.Parse("127.0.0.1"), 0);
listener.Start();
int port = ((IPEndPoint)listener.LocalEndpoint).Port;
PortNumberReady?.Invoke(port);
while (true)
{
TcpClient remote;
try { remote = listener.AcceptTcpClient(); }
catch { break; }
IPEndPoint ep = (IPEndPoint)remote.Client.RemoteEndPoint;
ClientConnected?.Invoke(ep);
Stream stream = remote.GetStream();
byte[] buf = new byte[8192];
while (true)
{
try
{
int read = stream.Read(buf, 0, buf.Length);
if (read == 0) throw new Exception("Client disconnected");
string msg = Encoding.Unicode.GetString(buf, 0, read);
MessageReceived?.Invoke(msg);
}
catch (Exception ex)
{
ClientLost?.Invoke(ex.Message);
break;
}
}
}
}
public void StopListen()
{
try { listener.Stop(); listener = null; workerThread.Abort(); } catch { }
}
}
使用雙層 while 迴圈處理多用戶連線,但同步阻塞模式下一次僅能服務一個用戶。四大事件供 UI 訂閱。