java网络编程1

1. C/S架构通信原理

- 角色与交互模式:客户端(client)主动发起通信请求,服务器(server)被动接收通信并给予响应。如同生活中顾客向商家咨询商品信息,顾客主动询问,商家被动应答 。常见交互为一问一答模式,不过也存在其他模式。

- 多客户端服务:服务器通常要为多个客户端提供服务,类似一个大型超市要服务众多顾客。

2. 简单网络程序示例(回显服务器Echo Server)

- 服务器端:

- 核心任务三步:从客户端读取请求内容、依据请求计算响应(回显服务器是直接将请求作为响应)、把响应返回给客户端。

- 代码中使用 DatagramSocket 创建socket对象,若端口被占会抛 SocketException 异常 。通过死循环持续处理客户端请求, receive 方法用于接收数据报,若没收到会阻塞等待。

- 客户端:

- 主要操作四步:从控制台读取用户输入内容、通过网络发给服务器、从服务器读取响应、将响应显示到控制台。

- 创建客户端时需指定服务器的IP和端口,构造 socket 对象时操作系统自动分配空闲端口。

3. 网络通信关键要素

- Socket API:以UDP为例, DatagramSocket 用于创建socket对象,关联网络通信的五元组(源IP、源端口、目的IP、目的端口、协议类型) 。端口号范围0 - 65535 ,0 - 1024为知名端口号,一般给系统预留协议服务器使用,自定义代码最好避开。可通过尝试绑定或 netstat -ano 命令查看端口占用情况。

- 跨主机通信准备:要完成跨主机通信,后续涉及把服务器程序打成jar包、Linux服务器操作、开启云服务器防火墙等内容。

- UDP特性 :

- 无连接:不像TCP要先建立连接,可直接收发数据。

- 面向数据报:数据传输以数据报为单位。

- 全双工:可同时进行数据的发送和接收。

4. 代码相关注意事项

- 服务器端绑定端口时,一个端口同一时刻只能被一个进程绑定,若冲突会失败抛异常。

- 客户端指定固定端口易与其他程序冲突,所以通常由系统自动分配端口。

 

服务器端关键代码片段

 

// 创建socket对象

private DatagramSocket socket;

// 构造方法

public EchoServer(int port) throws SocketException {

    socket = new DatagramSocket(port);

}

while (true) {

    // 1. 读取请求并解析

    // 1) 创建一个空白的DatagramPacket对象

    DatagramPacket reqPacket = new DatagramPacket(new byte[4096], 4096);

    socket.receive(reqPacket);

    // 3) 把DatagramPacket中的数据解析成字符串. 只需要从DatagramPacket取到有效的数据即可.

    String request = new String(reqPacket.getData(), 0, reqPacket.getLength());

    // 2. 根据请求计算响应

    String response = process(request);

    // 3. 把响应写回到客户端

    // 1) 把响应构造成DatagramPacket对象

    DatagramPacket respPacket = new DatagramPacket(response.getBytes(), response.getBytes().length, reqPacket.getSocketAddress());

    // 2) 把DatagramPacket写回到客户端.

    socket.send(respPacket);

    // 4. 打印日志.

    System.out.printf("[%s:%d] req: %s, resp: %s\n", reqPacket.getAddress(), reqPacket.getPort(), request, response);

}

 

 

客户端关键代码片段

 

public EchoClient(String serverIp, int serverPort) {

    this.serverIp = serverIp;

    this.serverPort = serverPort;

}

socket = new DatagramSocket();

while (true) {

    // 1. 从控制台读取用户输入的内容

    // 2. 构造成UDP请求, 并发送. 不光要填内容, 还要填服务器的地址和端口.

    DatagramPacket reqPacket = new DatagramPacket(request.getBytes(), request.getBytes().length, InetAddress.getByName(serverIp), serverPort);

    socket.send(reqPacket);

    // 3. 读取服务器的响应.

    DatagramPacket respPacket = new DatagramPacket(new byte[4096], 4096);

    socket.receive(respPacket);

    // 4. 把响应显示到控制台.

    String response = new String(respPacket.getData(), 0, respPacket.getLength());

    System.out.println(response);

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值