- 禁止白嫖 T > T
- 点点赞呗
文章目录
- JavaEE & UDP简易翻译服务器 & 网络编程示例2 & CTP回显服务器,回显客户端
- 1. UDP简易翻译服务器
- 1.1 重写方法
- 1.2 设计翻译服务器
- 1.3 书写main方法启动服务器测试
- 2. TCP网络编程示例
- 2.1 ServerSocket 与 Socket
- 2.1.1 ServerSocket的构造方法
- 2.1.2 ServerSocket的核心方法
- 2.1.3 Socket的构造方法
- 2.1.4 Socket的核心方法
- 2.1.5 长连接与短连接
- 2.2 基于CTP 的 Socket 写一个简单的客户端服务器程序
- 2.2.1 CTP回显服务器
- 2.2.1.1 ServerScoket对象与构造方法
- 2.2.1.2 start启动方法
- 2.2.1.3 processConnect细节
- 2.2.2 CTP回显客户端
- 2.2.2.1 指定服务器Socket对象与构造方法
- 2.2.2.2 start启动方法
- 2.2.2.3 补充说明
- 2.2.3 测试与总结
Ctrl + O 重写process方法:
快速记忆小技巧:
而符合这种需求的数据结构就是:哈希表
public static void main(String[] args) throws IOException {
UDPDictServer udpDictServer = new UDPDictServer(9090);
udpDictServer.start();
}
如果没有学UDP建议先学UDP!
传送门:JavaEE & 网络编程示例1 & UDP套接字数据报编程 == 一发一收
方法名 | 方法说明 |
---|---|
ServerSocket(int port) | 服务器socket对象构造方法【指定端口号】 |
方法名 | 方法说明 |
---|---|
Socket accept() | 建立连接 |
void close() | 关闭socket【文件】对象 |
socket对象如果周期很长,一般是不需要关闭的,因为关闭时一般意味着程序终结,资源自动回收
accept方法是跟客户端建立连接的方法,后面写代码时重点说明
返回的Socket对象,即可以代表服务器与客户端的连接,也可以代表客户端与服务器的连接~
方法名 | 方法说明 |
---|---|
Socket(String host, int port) | 指定IP与端口号 |
方法名 | 方法说明 |
---|---|
InetAddress getInetAddress() | 返回Socket对象的IP地址 |
InputStreamgetInputStream() | 返回控制这个socket文件的输入流 |
OutputStreamgetOutputStream() | 返回控制这个socket文件的输出流 |
而他们对应的是字节流 ==> TCP面向字节流
这就是短连接
这就是长连接
对于接下来的代码,考虑到多条请求,我做出如下规定:
对于后面的代码设计,是按长连接来设计的!
同样的,分为服务器与客户端:
public class TCPEchoServer {
private ServerSocket serverSocket = null;
public TCPEchoServer(int port) throws IOException {
this.serverSocket = new ServerSocket(port);
}
}
public void start() throws IOException {
System.out.println("服务器启动!");
while(true) {
Socket clientSocket = serverSocket.accept();//建立连接
processConnect(clientSocket); // 连接成功后进行一些操作~
}
}
你可能有一个疑惑:
如以下关系:
public void processConnect(Socket clientSocket) throws IOException {
System.out.printf("[%s:%d] 客户端上线\n", clientSocket.getInetAddress().toString(),
clientSocket.getPort());
try(InputStream inputStream = clientSocket.getInputStream();
OutputStream outputStream = clientSocket.getOutputStream()) {
Scanner scanner = new Scanner(inputStream);
//这个对象将自动读取【字节流/其他流】为【字符流】
PrintWriter printWriter = new PrintWriter(outputStream);
//这个对象将自动写入【字符流】化为【字节流/其他流】
while(scanner.hasNext()) {//死循环了,除非客户端关闭~
String request = scanner.next();//nextLine有坑很烦
String response = process(request);
printWriter.println(response);//换行记得加~
printWriter.flush();
System.out.printf("[%s : %d] 发来请求:%s, 将对其返回响应:%s\n", clientSocket.getInetAddress().toString(),
clientSocket.getPort(), request, response);
}
System.out.printf("[%s:%d] 客户端下线\n", clientSocket.getInetAddress().toString(),
clientSocket.getPort());
} catch (IOException e) {
e.printStackTrace();
} finally {
clientSocket.close();
}
}
讲解:
获得请求并计算
回显计算:
public String process(String request) {
return request;
}
这里的flush特别重要,当你flush后,才能算真正输出了~
打印日志~
public class TCPEchoClient {
Socket socket = null;//此socket对象代表了服务器的socket文件~
public TCPEchoClient(String host, int port) throws IOException {
this.socket = new Socket(host, port);
//这个过程客户端主动连接了服务器,这样就可以被服务器的accept接受~
//而服务器的accept返回的对象,默认填上了客户端的IP与端口号
}
}
public void start() {
Scanner scanner = new Scanner(System.in);
try (InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream()){
PrintWriter printWriter = new PrintWriter(outputStream);
Scanner scannerFromServer = new Scanner(inputStream);
while(true) {
System.out.print("-> ");
String request = scanner.nextLine();
printWriter.println(request);
printWriter.flush();
String response = scannerFromServer.next();//如果为空,则需要等待对方flush
System.out.printf("[%s : %d] 收到请求:%s, 返回响应:%s\n", socket.getInetAddress().toString(),
socket.getPort(), request, response);
}
} catch (IOException e) {
e.printStackTrace();
}
}
讲解:
可能会更加难理解,但是也简化了UDP反复制作“数据报”的过程,并且是有连接的~
长连接是指一个服务器一段时间内反复服务一个客户端
并不是一次性发送多条请求,得到多条响应~
public static void main(String[] args) throws IOException {
TCPEchoServer tcpEchoServer = new TCPEchoServer(9090);
tcpEchoServer.start();
}
public static void main(String[] args) throws IOException {
TCPEchoClient tcpEchoClient = new TCPEchoClient("10.61.10.239", 9090);
tcpEchoClient.start();
}
运行测试(“死锁”版):
运行测试(正常版):
总结图示:
文章到此结束!谢谢观看
可以叫我 小马,我可能写的不好或者有错误,但是一起加油鸭!后续网络编程的博客会陆续更新,敬请期待!