什么是socket?
将底层复杂的协议体系,执行流程,进行了封装,封装完的结果,就是一个SOCKET了,也就是说,SOCKET是我们调用协议进行通信的操作接口。
UDP:无连接,不可靠传输,面向数据包 全双工
TCP:有连接 可靠传输 面向字节流 全双工
服务器工作流程: 读取请求并解析
2根据请求计算响应
3把响应写回服务器
UDP:
DatagramSocket:代表socket文件,操作系统操作网卡,是把网卡当作特殊的文件,称为socket文件.
send(DatagramPacket):发送数据
receive(DatagramPacket):接受数据
工作流程
服务器代码:
package UDP;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;
public class UDPechoServer {
//网络编程,socket用来操作网卡
private DatagramSocket socket = null;
//服务器一定要绑定一个端口号,因为服务器是网络传输中被动的一方,如果让操作系统
//随机分配,那么客户端就不知道这个服务器端口是什么,也就无法进行通信.
//如果随机分配 每次重启服务器换一个端口号,那相当于学校里的教室每天都换,学生不一定能找到自己的教室.
public UDPechoServer(int port) throws SocketException {
socket = new DatagramSocket(port);
}
public void start() throws IOException {
System.out.println("启动服务器");
while (true) {
//读取请求
//receive是一个输出型参数,需要先构建一个packet交给receive进行填充
DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);
socket.receive(requestPacket);//receive的内容来自于网卡,读取网卡填充进入request
String request = new String(requestPacket.getData(),0,requestPacket.getLength());
//将Packet转成字符串处理
//计算响应
String response = process(request);
//返回响应
DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,
requestPacket.getSocketAddress());
//packet不认字符 是按照字节数进行处理
socket.send(responsePacket);
System.out.printf("[%s:%d] req: %s resp %s \n",requestPacket.getAddress().toString(),
requestPacket.getPort(),
request,response);
}
}
public String process(String str){
return str;
}
public static void main(String[] args) throws IOException {
UDPechoServer udPechoServer = new UDPechoServer(9090);
udPechoServer.start();
}
}
客户端代码
package UDP;
import java.io.IOException;
import java.net.*;
import java.util.Scanner;
public class UDPechoClient {
private DatagramSocket socket = null;
/**
* 需要指定服务器ip和端口
*/
private String ServerIp = null;
private int ServerPort = 0;
//客户端的端口可以由操作系统分配
//服务器的端口和ip需要指定
public UDPechoClient(String ServerIp,int ServerPort) throws SocketException {
socket = new DatagramSocket();
this.ServerIp = ServerIp;
this.ServerPort = ServerPort;
}
public void start() throws IOException {
System.out.println("客户端启动");
Scanner sc = new Scanner(System.in);
while (true){
//1读取数据
System.out.println("请输入要发送的数据");
String request = sc.next();
if (request.equals("exit")){
System.out.println("goodbye");
break;
}
//构造UDP请求,并发送
/**
* 构造这个Packet的时间,需要把ip和端口传过来,
* 但是ip是字符串形式们需要利用InetAddress.getByName进行转换
*/
DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),request.getBytes().length,
InetAddress.getByName(ServerIp),ServerPort);
socket.send(requestPacket);
//3读取响应,解析
DatagramPacket responsePacket = new DatagramPacket(new byte[4096],4096);
socket.receive(responsePacket);
String response = new String(responsePacket.getData(),0,requestPacket.getLength());
System.out.println(response);
}
}
public static void main(String[] args) throws IOException {
UDPechoClient client = new UDPechoClient("127.0.0.1",9090);
client.start();
}
}