Qing_C-S通讯Socket的详细做法
背景:我们用Scoket实现客户端和服务端的通信。要求如下:
1、一个服务端可以监听多个客户端
2、客户端和服务端之间可以对话
3、服务端发消息至客户端
4、服务端停止监听,客户端会显示断开连接
5、客户端断开连接,服务端会显示该客户端断开
将来可能的题目要求,即待实现:
6、客户端和客户端的通话(应通过服务端连接,不允许客户端彼此之间互相连接)
7、客户端和客户端的断开以及登陆的即时显示
8、如果客户端和客户端是局域网,那么可以考虑是否让他们直接连接
9、做成QQ的形式。改善布局。以及界面
10、其它
工具:VS2010旗舰版
语言:C#
现在的布局如下:
socket通信报文格式
现在开始说明如何实现这整体的布局:
服务端:
1、SendMessage和ReceivedMessage是使用richTextBox,也就是富文本编辑器。
2、服务端的停止监听,在刚打开From的时候是开始监听,点击开始监听会变成停止监听,实现如下:
3、连接Socket的方法:
先写好端口:
然后开始监听:
4、接收到得消息如何进行处理?
是登陆消息?还是退出消息?还是对话消息?我们该怎么去区分他呢?
答案就是,在客户端传来的字段中,加入标志段:
比如“talk,你好啊”,就是说话
比如“login,”就是登陆进来
比如“logout,”就是登出
所以,我们在接收到的字段需要处理,根据“,”分开,得到标识符和消息。主要是因为编码问题等。其实可以不经过这个方法。处理的方法如下:
然后接收消息的语句如下:
无论是登陆等处还是其他。都需要对消息进行写入
写入包括两点:一是吧消息写入消息列表,二是把用户写入用户列表,也就是客户端列表。
这里我通过两个方法:
AddItem()方法是把某些消息写入富文本编辑器中:如图:
refresh()方法是刷新用户表。从当前存储的用户列表中读取,比较简单:
所以,为了满足MVC思想,也就是页面层和数据分开。我们改页面只是根据数据改。
就是说我们不直接对页面操作,我们是每次读取数据。只要数据改了,页面自然改了。所以我的refresh是只是一个简单的刷新、那么问题来了:提取消息的方法呢:如下
5、这样,接收消息就全部做完了,现在就是如何发送消息给客户端。
实现如下:
那么,接下来就应该是解释SendToClient()函数了吧。
该函数包含两个参数。一个Socket和一个String,也就是把String发送给Socket。
实现如下:
之所以代码中包含一个暂停函数,是为了保证交互性:数据传过去之后暂停10毫秒,然后才显示出来。这就是所谓的所见不一定是所得。
这里可以加入一个检测是否发送成功,但是我就不加了。
因为我这里发送的时候需要点击发给谁,如果没有连接,就无法点到他。所以,服务端到此结束。
6、当Form退出的时候,我们需要所有的资源退出:同时,我们需要传递参数给客户端。
传递给客户端的话,为了简便,我们直接实现发送“LogoutYuko”。
这样,当我们客户端接收到这个字段,表示服务端退出了,这是一个不完美的做法。因为我懒。。。对于每一个连接Socket,进行Close
对于每一个Thread,进行Abort
客户端
1、SendMessage和ReceivedMessage是使用richTextBox,也就是富文本编辑器。
2、同服务端理,客户端的连接,再点击之后会失效。因为不允许重复连接。
本可以实现点击之后变成断开,但是断开之后重连比较麻烦,我还没去搞。待实现。代码如下:
3、当客户端启动之后,服务端如果没有开始监听,客户端不会不断的去连接。
同时客户端下方的信息会不断地提示正在连接,连接失败,正在连接,直到连接成功。
连接好之后会出现
实现如下:
4、由上图可知:我们的连接的函数是:socket.Connect(ipe)。用ted判断是否连接成功。那么,点击登陆的时候,也就是执行一个函数:点完之后就不能再点了。
init的方法(和服务端一样,建立线程,加入列表):
conn的方法如下(3中详细介绍了):
对于第61行的线程,也就是执行接收数据的方法:
实现和服务端不同,因为这里只要接收对话就可以。
然后其他的东西,就差不多了。
至此,应该已经解决了大多数的代码问题。
然后,怎么执行这个项目呢?
因为我们一个解决方案里面有两个项目,但是只能启动一个。所以呢。我们在两个项目里面都生成。这样,在对应的项目的bin的debug里面,可以得到生成的exe。
这样,就可以实现同时执行两个项目了。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。