public interface IMessageReceiver {
event MessageReceivedEventHandler MessageReceived; // 接收到发来的消息
event ConnectionLostEventHandler ClientLost; // 远程主动断开连接
event ClientConnectedEventHandler ClientConnected; // 远程连接到了本地
void StartListen(); // 开始侦听端口
void StopListen(); // 停止侦听端口
}
我记得曾经看过有篇文章说过,最好不要在接口中定义事件,但是我忘了他的理由了,所以本文还是将事件定义在了接口中。
2.4主程序Talker
而我们的主程序是既可以发送,又可以接收,一般来说,如果一个类像获得其他类的能力,以采用两种方法:继承和复合。因为C#中没有多重继承,所以我们无法同时继承实现了IMessageReceiver和IMessageSender的类。那么我们可以采用复合,将它们作为类成员包含在Talker内部:
public class Talker {
private IMessageReceiver receiver;
private IMessageSender sender;
public Talker(IMessageReceiver receiver, IMessageSender sender) {
this.receiver = receiver;
this.sender = sender;
}
}
现在,我们的程序大体框架已经完成,接下来要关注的就是如何实现它,现在让我们由设计走入实现,看看实现一个网络聊天程序,我们需要掌握的技术吧。
C#网络编程基础(篇外篇)
这部分的内容请参考 C#网络编程 系列文章,共5个部分较为详细的讲述了基于Socket的网络编程的初步内容。
编写程序代码
如果你已经看完了上面一节C#网络编程,那么本章完全没有讲解的必要了,所以我只列出代码,对个别值得注意的地方稍微地讲述一下。首先需要了解的就是,我们采用的是三个模式中开发起来难度较大的一种,无服务器参与的模式。还有就是我们没有使用广播消息,所以需要提前知道连接到的远程主机的地址和端口号。
1.实现IMessageSender接口
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[] buffer = Encoding.Unicode.GetBytes(msg.ToString());
streamToServer.Write(buffer, 0, buffer.Length);
return true;
}
} catch {
return false;
}
}
// 注销
public void SignOut() {
if (streamToServer != null)
streamToServer.Dispose();
if (client != null)
client.Close();
}
}










