开学一个月了,主要在学习网络通信。感觉这一块需要相当好的逻辑能力和全局感,因为代码量很大,需要调用的函数也很多,需要遵守的读写顺序,规则,以及流程也有很多。所以总结是十分有必要的!为了理清思路好好的往后面学,从今天开始我会每天更新一点我之前做过的有关通信内容的总结。这一块我目前大致做到了6步:1,实现简单的可以读取字符串的服务器,用DOS系统下自带的客户端登陆。2,在这基础上实现多线程服务器,允许和多个客户同时通信。3,简单的客户端。4,实现有界面的通信客户端和服务器。5,XMPP风格协议的通信客户端和服务器。6,字节流协议传文件。那么闲话先不多说,让我直入主题。
首先,谈一下如何实现一个简单的可以读取字符串的服务器。让我们先来理清楚如何通信这个概念,实现通信无非就是要在服务器和客户端之间搭建一个可以交流的管道,
1.我们首先创建一个服务器ServerSocket对象
// 在指定的端口上构造服务器对象
java.net.ServerSocket ss = new java.net.ServerSocket(port);
System.out.println("服务器构建成功,等待端口" + port);
2.再通过调用它的accept()方法等待一个客户端Socket对象连接进入,这里我用了while (true)的方法,目的是为了让服务器进入循环等待,即如果一个客户端断开连接,只要服务器不关闭它还可以再次连接。当然这里的while(true)用的是有缺陷的,这还需要在以后的代码中继续改进!
while (true) {//让服务器进入循环等待,即如果一个客户端断开连接,只要服务器不关闭它还可以再次连接
java.net.Socket client = ss.accept();
3.当一个客户端连接进入以后我们就从这个Socket对象上得到输入输出流来搭建这个管道。
//从连接对象上得到输入流对象,用于读取
java.io.InputStream ins = client.getInputStream();
java.io.OutputStream ous = client.getOutputStream();
管道一旦连通搭建好就可以收发消息啦~
由于还要收发字符串,所以我们这里分析一下读取字符串的方法。首先,通信的实质是传输一个个的字节,所以,这里我们构建一个字符串缓冲区,来读取每一个字节。
//创建一个字符串缓冲区
StringBuffer stb = new StringBuffer();
读取字符串的过程中,read()方法也要产生一个阻塞。也就是说我们要读取完整的一句话。这里我用回车换行符来实现这个阻塞,即只有读取到一个回车换行符的时候才算读取了完整的一句话!回车换行符是”\r\n”,r对应的字节是10,而n对应的字节是13,所以只要读取到一个字节值为13或10的字节,我们就把它组成一句话,并让服务器读取这句话:
char c=0;
while(c!=13){
//遇到一个换行就是一句话
int i = ins.read();//读取客户机发来的一个字节
c=(char)i;//将输入的字节转化为一个char
stb.append(c);
}
最后再把上述的封装成一个方法,这样每次服务器调用这个方法就等于是读取了客户家发来的完整的一句话了!
下面我把上述描述的组合起来,给出实现最最基础的服务器的源代码:
public class ChatServer {
public static void main(String args[]) {
ChatServer cs = new ChatServer();
int port = 9090;
cs.setUpServer(port);
}
// 在指定端口上启动服务器
public void setUpServer(int port) {
try {
// 在指定的端口上构造服务器对象
java.net.ServerSocket ss = new java.net.ServerSocket(port);
System.out.println("服务器构建成功,等待端口" + port);
// 调用服务器accept方法,当有客户机连上时,返回代表他们之间连接的socket对象
while (true) {//让服务器进入循环等待,即如果一个客户端断开连接,只要服务器不关闭它还可以再次连接
java.net.Socket client = ss.accept();
// 调用处理客户机与服务器通信的方法
processClient(client);
}
} catch (Exception ef) {
ef.printStackTrace();
}
}
public void processClient(java.net.Socket client) {
try {
String clientAdder = client.getRemoteSocketAddress().toString();
System.out.println("连接进的客户地址是:" + clientAdder);
// 从连接对象上得到输入流对象,用于读取
java.io.InputStream ins = client.getInputStream();
// 从连接对象上得到输出流对象,用于写入
java.io.OutputStream ous = client.getOutputStream();
// 刚连接上时给客户机发消息
String outStr = clientAdder + "欢迎你!\r\n";// 每条消息事宜\r\n结尾的行消息
ous.write(outStr.getBytes());
ous.flush();
String input = readString(ins);
while (!"bye".equals(input)) {// 当客户机输入了一个bye,即断开连接
System.out.println("客户机发来的消息是:" + input);
outStr = "服务器收到了你的消息" + input + "\r\n";
ous.write(outStr.getBytes());
ous.flush();
input = readString(ins);// 再次读取客户机发来的消息
}
// 如果客户机发送了"bye"消息,即要求退出
outStr = "再见\r\n";
ous.write(outStr.getBytes());
ous.flush();
// 关闭连接
client.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private String readString(InputStream ins) throws Exception {
// 创建一个字符串缓冲区
StringBuffer stb = new StringBuffer();
char c = 0;
while (c != 13) {
// 遇到一个换行就是一句话
int i = ins.read();// 读取客户机发来的一个字节
c = (char) i;// 将输入的字节转化为一个char
stb.append(c);
}
String input = stb.toString().trim();
return input;
}
}
总结一下这个最简单的服务器,我觉得我们首先要了解一个通信的实质,那就是在客户端和服务器之间搭建一个可以沟通的桥梁这里通过服务器的accept方法连上一个客户端,在调用客户端的输入输出流搭建通信管道。这里有两处阻塞的地方,第一是服务器的aceept方法来等待连接的时候,还有一个是读取字符串的时候。难点大致就是这些。最后通过cmd打开命令行 输入telnet 你的IP地址 端口号 就可以实现聊天啦~当然这个服务器还有很多的缺陷需要改进,具体的请看以后的日志~
分享到:
相关推荐
这篇名为“网络通信基础第五式——实现自定义字节流协议的KTM”的博客文章聚焦于如何设计和实现一个自定义的字节流协议,名为KTM(King Talk Message)。本文将深入探讨这个主题,解析其背后的原理和技术细节。 ...
在这个“客户端和服务器互联——计算机网络课程设计”项目中,我们聚焦于实现一个Echo程序,它是一个简单的聊天工具,能够模拟服务器与多个客户端之间的信息交互。 首先,我们需要理解“服务器”和“客户端”的概念...
在"QT——服务器+客户端进行tcp通信代码.rar"这个压缩包中,包含了一个客户端(client)和一个服务器端(server)的工程,这让我们有机会深入理解QT如何实现TCP/IP通信。 首先,TCP(传输控制协议)是互联网协议栈...
在Wireshark数据包分析实战第三版中,我们聚焦于一个特定的问题——11.4.4章节讨论的“通信缓慢——服务器延迟”。这个场景通过分析一个名为"latency4.pcap"的网络捕获文件来展示。在图11-25中,我们看到在服务器...
在本项目中,我们将探讨如何使用C++...总的来说,这个“C++ QT项目——一个简易的用户化界面(Qt命令行模式)”是学习Qt和C++结合的绝佳起点,通过实践,你可以逐步掌握Qt的精髓,为后续的图形界面开发打下坚实的基础。
总结来说,这个简易服务器框架结合了Windows平台的优势、libevent的高效事件处理、protobuf的序列化能力以及C++11的现代编程特性,为开发者提供了一个快速开发网络服务的起点。通过理解这些关键技术,开发者可以更好...
《实现P2P网络通信——基于Java的深度解析》 P2P(Peer-to-Peer)网络通信是一种去中心化的网络架构,其中每个节点既是服务的提供者也是服务的消费者。这种模式在分布式系统、文件共享、流媒体传输等领域有着广泛...
客户端发送一个SYN包请求连接,服务器响应一个SYN+ACK包,最后客户端再回应一个ACK包,至此连接建立成功。 2. **数据传输**:连接建立后,双方可以开始数据交换。TCP保证数据的有序性和无丢失性,通过序列号和确认...
在这里,可能会创建一个隐式Intent,调用系统相机应用来录制视频,然后返回结果到我们的应用。 3. **文件存储**:拍摄的视频需要暂时存储在设备上,Android提供了多种存储选项,如内部存储、外部存储(SD卡)。开发...
1. **初始化**: 在客户端程序中,你需要创建一个CAsyncSocket对象并调用其成员函数`Create()`来初始化套接字。这个函数会分配一个套接字句柄,并将其设置为非阻塞模式。 2. **连接服务器**: 使用`Connect()`函数与...
在TCP通信过程中,还会涉及到端口号,每个通信进程都有一个唯一的端口号标识,客户端和服务器端通过特定的端口进行通信。例如,HTTP默认使用80端口,HTTPS使用443端口。 除此之外,TCP还具有拥塞控制策略,如慢启动...
在本篇中,我们将深入探讨如何使用Linux网络编程技术,特别是epoll和多线程机制,来构建一个简单的跨平台聊天应用。这个应用涉及到Linux服务器端和Windows客户端的交互,让我们逐一解析其中的关键知识点。 首先,`...
1. **Socket通信**:SwiFTP利用Java的Socket类进行网络通信,创建监听套接字来接收客户端的连接请求,并通过Socket对象处理数据传输。 2. **线程管理**:为了处理并发连接,SwiFTP使用线程池来管理每个FTP会话,确保...
5. **图片处理**:压缩包中的`103307b65cfm6lm1z1lkmd.jpg`可能是一个示例图片,可能用于显示更新信息的提示图标或者作为应用的logo。Android提供了多种处理图片的方法,如`BitmapFactory`,以及第三方库如Glide或...
客户端向服务器发送消息,服务器回应客户端,然后一次读写就完成了,这时候双方任何一个都可以发起close操作。长连接是指客户端向服务器发起连接,服务器接受客户端连接,双方建立连接。客户端与服务器完成一次读写...
Socket是网络通信的基础,它允许两个网络节点(在这里是客户端和服务器)之间建立连接并交换数据。在Java中,`java.net.Socket` 和 `java.net.ServerSocket` 类提供了实现这一功能的接口。客户端通过创建Socket实例...
在本资源中,我们主要探讨的是一个基于Android平台的简易微信客户端和服务器的源代码实现。这个项目旨在帮助开发者理解如何构建类似微信这样的即时通讯应用的基础架构,包括客户端与服务器之间的通信、数据传输以及...
标题中的“网络通讯客户端服务的完整代码.rar_vc 网络通讯_服务器_服务器 保存_网络编程 TCP/IP”表明这是一个使用VC++编写的网络通信项目,包含了客户端和服务器的完整代码,支持TCP/IP协议。这个项目的核心功能是...
本项目提供了一个服务器和一个客户端的实例,旨在演示如何使用C#语言实现基于套接字的网络通信,并结合`select`函数进行多路复用。下面将详细解释这些关键知识点。 1. **网络套接字(Socket)**: - 网络套接字是...
程序员可以通过调用系统函数创建Socket,并通过这个Socket进行数据的读写,从而实现网络通信。 - **流式Socket (Stream Socket)**:这是一种面向连接的Socket,基于TCP协议。它提供了可靠的数据传输服务,适用于...