学习通信基础快一周了。到了服务器、客户端的实现,进度很自然地变慢了。
上课中的两点,觉得有些体会:
1.减少线程之间依赖关系,
最基础、底层的类一改动,那么以它为基础的类都要受影响,所以,减少依赖关系。
2.区分整体框架设计和细节完善问题
明白当前是完成搭建框架,还是完善具体细节。
自顶向下设计,先完成类的设计,再完善具体方法。
先写服务器,客户端暂时由telnet命令产生。
其中,有几个地方花了较多的时间:
1.服务器接收客户端的消息,readString方法
(1)服务器读入正确的消息。
自己定义:按回车后,服务器接受一条消息。而按回车键,先后读入字节13(回车"\r")和字节10(换行"\n")两个字节。每次,读输入流中一句话的结束标志是读到字节13,所以,读的每句话都要对上一次按回车后,遗留在在输入流中未读入的的换行字节10作处理。
(2)点击客户端右上角关闭时,读取字节-1,若此时输入未结束,则可能进入死循环。完善服务器读取字节的条件,跳出读取一句话的循环。
//服务器读客户端的一句话,
public String readString(java.io.InputStream ins){
//创建StringBuffer
StringBuffer strb=new StringBuffer();
try{
int t=ins.read();
//按回车,字节为13、10
//当关闭右上角时,t=-1
while(t!=13 && t!=-1){//按回车,或关闭右上角时,读客户端的输入流结束
strb.append((char)t);//按右边数字键盘的Enter就不对了,就10一个字节
t=ins.read();
}
String str=strb.toString();
if(t!=-1){//正常输入
if(str.charAt(0)=='\n'){
return str.substring(1, str.length());
}else{//第一次回车之后
return str;
}
}
}catch(Exception ef){
ef.printStackTrace();
}
//输入一半时,点击右上角关闭按钮
return null;
}
客户端结束对话的while循环,输入“end”结束对话:
while(!"end".equals(str) && str!=null ){
System.out.println("进入while(end)中");
//二......转发给其他客户端
ChatTools.sendMsg2Others(this, str);
str=readString(ins);
}
2.加了服务器界面后,需要正常的启停控制。
设计启停功能:
(1)未按启动之前,线程休眠等待,
(2)按启动之后,服务器创建成功
(3)按停止之后,服务器关闭
循环执行(1)(2)(3)。
3.当在accept的时候,关闭ServerSocket对象,或者在read的时候,关闭Socket对象,则会捕获SocketException,而这些在阻塞状态下关闭,产生的异常是正常的,不可能避免。只要捕获异常后,适当处理,就可以了。
4. 当关闭服务器后,服务器仍可以向客户端发送发消息。
这个解决得比较快,将服务器接收客户端消息的线程对象ChatThread从队列中移除就可以了。当服务器没有发送对象时,消息就发不出了。
5. 当关闭服务器后,客户端仍然可以向服务器发送消息。
问题的本质是服务器接收客户端消息的线程没有执行结束,即run方法没有执行结束。
(1)原本以为服务器的线程会影响服务器接收客户端消息的线程ChatThread。因为,线程ChatThread是从服务器的线程中产生的。测试之后,两个线程是独立的,两者之间的结束,互不影响。
(2)强行关闭ChatThread
由于,线程数量未知,不便控制,所以将他们放入队列处理。除了队列,暂且想不出其他方法来解决。当服务器关闭时,将所有的Socket对象强制关闭,流也就没有了。那么run方法就执行完了,服务器就无法接收客户端消息了。
这里,要强调一点,要清楚地知道每个类的属性和方法,最好画一幅类之间的关系图。避免重复处理。比如,Socket是ChatThread类的属性,创建队列ArrayList<ChatThread>之后,那么就不必要再创建ArrayList<Socket>了。
进入到有界面的服务器之后,进度就特别慢。有时候,就要时不时地理清思路,考虑方法要实现什么功能。回顾以前的代码,也有助于更好地理解概念。
如由于代码较多,理了一下服务器的思路:
1. 创建服务器,
2. 服务器处于循环等待客户端连接的阻塞状态
3. 客户端连接成功后,得到连接对象Socket (连接时,验证用户名、密码)
4. 从Socket对象得到输入输出流
5. 处理服务器与客户端ct的对话
5.1 服务器向客户端发送消息
5.2 服务器接收客户端发送的消息,线程
5.2.1将新的客户端,加入线程队列
5.2.2将一个客户端发送的消息,通过服务器发送给其他客户端
5.2.3将下线的客户端,从线程队列中删除
6.关闭服务器,关闭所有Socket对象,清空队列。
其中,也用到了较多的队列操作,一般有如下操作,若忘了其中一个步骤,就要找错误了:
1.加入队列
2.从队列中移除某个对象
3.程序结束,清空队列
这个还是要多练习,在练习的过程中理解,多学习。
分享到:
相关推荐
2. **创建Socket连接**:客户端创建`Socket`对象,连接到服务器的IP地址和端口号。 3. **获取输出流**:通过Socket对象的`getOutputStream()`方法获取`OutputStream`,这是发送数据的通道。 4. **发送文件数据**:...
在Android中,我们通常使用java.net.Socket类来创建Socket对象,实现客户端与服务器端的双向通信。Socket通信基于TCP/IP协议,确保数据的有序性和可靠性。 二、Android客户端Socket通信步骤 1. 创建Socket对象:...
总的来说,这个项目提供了一个基础的框架,展示了如何使用ESP8266作为TCP服务器,通过STM32控制,在AP模式下创建热点并进行网络通信。这对于学习嵌入式开发、物联网应用以及无线通信技术的人来说,是一个很好的实践...
1. **TCP服务器创建**:在LabVIEW中,你可以使用“创建TCP服务器”函数来启动一个服务器,指定监听的端口号。这个函数会返回一个句柄,用于后续的数据通信操作。 2. **数据发送与接收**:一旦客户端连接到服务器,...
同时,这也是学习网络编程和Socket通信基础的好方式。实践中,你可以扩展这些基本示例,例如实现更复杂的协议或处理多客户端连接。记得在实际部署时,要考虑到异常处理、安全性和性能优化等因素。
在Java中,我们可以使用Socket编程来创建客户端和服务器端的通信。Socket是网络通信的基本单元,它提供了进程间的通信连接。 在"客户机服务器通信模拟"项目中,服务器端通常会先启动,监听特定的端口(如默认的9999...
本教程将深入讲解C#中的Socket通信,包括客户端和服务器端的实现,以及如何通过源码学习相关知识。 首先,我们要理解Socket的基本概念。Socket,也称为套接字,是网络通信中的一个接口,它允许应用程序通过网络发送...
总的来说,全双工TCP服务器的搭建涉及网络编程基础、套接字操作、TCP协议原理以及进程管理等多方面知识,通过正确地编写和使用`server.c`和`client.c`代码,可以在Linux环境下实现稳定可靠的全双工通信。
3. 当有新的连接请求时,服务器会创建一个`QSslSocket`实例,用于与客户端进行安全通信。 4. 在`QSslSocket`上设置SSL选项,如启用特定的加密套件和验证策略。 5. 处理客户端的连接请求,读写数据。 客户端的实现...
1. **创建套接字**:服务器首先需要创建一个套接字,这是通信的基础。在Unix-like系统中,这通常通过调用`socket()`函数完成,指定协议族(如AF_INET)和协议类型(如SOCK_STREAM,对应TCP)。 2. **绑定IP和端口**...
在本项目中,"即时通信服务器代码-socket通信" 提供了一种多人聊天的解决方案,支持用户注册、添加和删除好友,以及创建群聊等功能。Socket编程是网络通信的基础,它允许两个程序通过网络进行数据交换,非常适合构建...
总的来说,“服务器到客户端的单向通信”是一个基础但重要的网络编程概念,广泛应用于各种实时信息推送服务。通过VS2010和C#,开发者可以构建出高效、可靠的系统,实现服务器对多个客户端的高效广播。这个项目中的...
在给出的代码中,服务器创建了一个新线程`LisThread`来运行监听任务,这样主线程就可以继续处理其他工作,而不会被监听过程阻塞。 此外,`GetIP()`函数用于获取本地主机的IP地址,这是为了让服务器知道自己的网络...
综上所述,"C# 服务器客户端一对多通信"涵盖了网络编程的基础理论、C#的Socket编程、多线程与异步处理、设计模式、安全性等多个方面,理解并掌握这些知识点是开发高效、稳定、安全的网络应用程序的关键。
在Linux操作系统中,服务器与客户端之间的通信是网络编程的基础,主要依赖于TCP/IP协议栈。本文将详细解析基于Linux的服务器与客户端通信实现过程,包括关键概念、原理以及代码实现。 首先,我们要理解服务器...
在Java编程领域,客户端-服务器通信是网络编程的基础,它允许不同计算机间的程序进行数据交换。在这个简陋版的实现中,我们不依赖JSON作为数据交换格式,而是可能使用了自定义的序列化方式或者纯文本格式。我们将...
本资源“网络通信基础 源代码”提供了一组基于VC++的网络编程源代码,旨在帮助学习者理解网络通信的基础概念,并通过实际操作来加深对服务器和客户端交互的理解。 首先,我们要了解网络通信的基础原理。网络通信...
通过以上分析,我们可以看出《服务器客户端通信工具1.0.zip》是一个涵盖了网络通信基础、异步编程、多线程处理等多个关键点的实用工具,对于学习和实践.NET框架下的网络编程具有很高的参考价值。
本教程将深入探讨如何使用C#语言实现客户端与服务器之间的通信,主要聚焦于Socket编程基础。C#提供了强大的网络编程支持,使得开发者能够轻松创建可靠的网络应用程序。 首先,我们要理解什么是Socket。Socket是网络...
总之,Windows Socket通信基础代码是学习网络编程的重要实践,通过这个简单的例子,可以深入了解TCP/IP通信的原理和流程,为进一步的网络应用开发打下基础。在实际使用中,还需要考虑网络环境、安全性、性能优化等多...