持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第26天,点击查看活动详情
Java网络编程(一)
前言
来自百科: socket()函数用于根据指定的地址族、数据类型和协议来分配一个套接口的描述字及其所用的资源。
操作系统将封装传输层协议(TCP/UDP), 提供socket接口给应用层,
在Java中提供了ServerSocket(TCP)和DatagramSocket(UDP)实现
我们以TCP为例, 用Java ServerSocket来编写一个简单的服务端
代码
// 绑定端口
ServerSocket server = new ServerSocket(8080);
while (true) {
// 阻塞等待接收连接请求
Socket accept = server.accept();
try (InputStream in = accept.getInputStream(); OutputStream out = accept.getOutputStream()) {
byte[] bytes = new byte[1024];
int len;
while ((len = in.read(bytes)) != -1) {
String content = new String(bytes, 0, len);
System.out.println(content);
out.write("ha".getBytes());
break;
}
}
}
启动上面代码, 我们来探究一下到底发生了什么, 我们使用Wireshark来抓取下相关请求看一看
- 这里是本地的地址, 选择回环地址就行
- 然后配置监听8080端口
- 打开
windows cmd, 输入telnet localhost 8080我们可以清晰的看出客户端与服务端的交互过程
不知道有没有小伙伴好奇浏览器请求8080端口会发生什么
这里由于我们的服务端代码没有处理http协议的逻辑, 所以浏览器直接异常了, 关于http协议的请参考http1.1 rfc
我们看下服务端的控制台, 因为我们输出了完整的请求数据
可以看到浏览器一个简单的
GET请求发过来这么多数据, 这也是为什么说http协议是头重脚轻了
简单改造下代码
// 绑定端口
ServerSocket server = new ServerSocket(8080);
while (true) {
// 阻塞等待接收连接请求
Socket accept = server.accept();
try (InputStream in = accept.getInputStream(); OutputStream out = accept.getOutputStream()) {
byte[] bytes = new byte[1024];
int len;
while ((len = in.read(bytes)) != -1) {
String content = new String(bytes, 0, len);
System.out.println(content);
String res = "ha";
out.write(("HTTP/1.1 200 \r\n" +
"Content-Type:application/json;charset=utf-8;" +
"Content-Length:" + res.getBytes().length + " \r\n\r\n" +
res).getBytes());
break;
}
}
}
再次浏览器请求, 可以发现已经正常了, 我们再用Postman发一个POST请求看看数据是啥样的
我们再来试一下websocket, 看下到底是啥样的
可以看到websocket本职还是http协议, 关于websocket协议可以参考websocket rfc
总结
可以看到, 我们使用ServerSocket建立服务端, 只需要再按照约定的协议处理请求响应数据, 就能愉快的通信了