目录
1.什么是网络编程
客户端:服务的使用方
服务器:服务的提供方
请求:一般是客户发起的
响应:
2.怎么进行网络编程
Java对每种操作系统做了进一步的封装,JDK中
3.Socket套接字
操作系统工作在传输层,TUP,UDP
面试题:请你说一下TCP与UDP的区别
3.1流套接字TCP
使用传输层
TCP
协议
以下为
TCP
的特点:
有连接
可靠传输
面向字节流
有接收缓冲区,也有发送缓冲区
大小不限
3.2数据报套接字UDP
使用传输层
UDP
协议
UDP
,即
User Datagram Protocol
(用户数据报协议),传输层协议。
以下为
UDP
的特点:
无连接
不可靠传输
面向数据报
有接收缓冲区,无发送缓冲区
大小受限:一次最多传输
64k
3.3举例对比TCP与UDP
1.有无连接:
TCP相当于打电话,接听方必须要接通电话双方才可以通信
UDP相当于发短信,双方有没有开机都不重要
2.可靠传输:
打电话时必须要经过拨号,接听后才可以通话,发短信发出去就不管了
如果数据包在传输过程中丢了,TCP会有重传机制,UDP丢了就丢了
3.面向字节流:
打电话说一个字对方就可以听到一个字
面向数据流:
发短信发一条条的信息对方接受到才可以阅读
4.全双工:
可以打电话也可以接电话,可以发短信也可以收短信
5.大小不限
电话的时间不限,短信的大小有限制
4.请求与响应
场景:一个人去餐馆吃饭
1.顾客给老板说来一份蛋炒饭(请求)
2.老板去做蛋炒饭,上桌(响应)
一问一答的过程
4.1Java中使用UDP
DatagramSocket
是
UDP Socket
,用于发送和接收
UDP
数据报。
服务器程序类似于在学校食堂开了一个档口李二面馆,学校食堂相当于操作系统,档口相当于端口号,李二面馆相当于应用程序进程
代码一旦被执行,服务端就被启动。
public class UDPEcho {
private DatagramSocket sever;
public UDPEcho(int port) throws Exception {
if(port>65535||port<1024){
throw new Exception("端口号必须在1024-65535之间");
}
//初始化服务器端的UDP服务,相当于开了一个面馆
this.sever=new DatagramSocket(port);
}
public void start() throws IOException {
System.out.println("服务器已启动");
//循环接受用户的请求
while (true){
//1.创建一个用于接受请求数据的DatagramPacket,封装了用户的真实请求
DatagramPacket requestPacket=new DatagramPacket(new byte[1024],1024);
//2.接收请求
sever.receive(requestPacket);
//3.从requestPacket获取数据
String request=new String(requestPacket.getData(),0,requestPacket.getData().length,"UTF-8");
//4.根据请求获取响应
String response=processor(request);
//5.把响应封装到DatagramPacket
DatagramPacket responsePacket=new DatagramPacket(response.getBytes(StandardCharsets.UTF_8),response.getBytes().length,requestPacket.getSocketAddress());
//6.发送数据
sever.send(responsePacket);
//7.打印日志
System.out.printf("[%s:%d]request:%s,response:%d",requestPacket.getAddress().toString(),responsePacket.getPort(),request,response);
}
}
private String processor(String request) {
return request;
}
public static void main(String[] args) throws Exception {
UDPEcho sever=new UDPEcho(9999);
}
}
4.2服务端与客户端执行关系
public class UDPEchoClient {
private DatagramSocket client;
//定义服务器的IP地址
private String serverIp;
//定义服务器的端口号
private int port;
private SocketAddress address;
/**
* 构造方法,指定服务器的IP和端口号
* @param serverIp
* @param port
*/
public UDPEchoClient(String serverIp,int port) throws SocketException {
this.client=new DatagramSocket();
this.serverIp=serverIp;
this.port=port;
this.address=new InetSocketAddress(serverIp,port);
}
//启动服务
public void start() throws IOException {
System.out.println("客户端已启动");
Scanner scanner=new Scanner(System.in);
while (true){
System.out.println("->");
String request=scanner.next();
//1.把请求内容包装成DatagramPacket
DatagramPacket requestPacket=new DatagramPacket(request.getBytes(StandardCharsets.UTF_8),request.getBytes().length,address);
//2.发送数据
client.send(requestPacket);
//3.接收响应
DatagramPacket responsePacket=new DatagramPacket(new byte[1024],1024);
client.receive(responsePacket);
String response=new String(responsePacket.getData(),0,responsePacket.getLength(),"UTF-8");
System.out.printf("requset:%s,response:%s\n",request,response);
}
}
public static void main(String[] args) throws IOException {
UDPEchoClient client=new UDPEchoClient("127.0.0.1",9999);
client.start();
}
}
public class UDPDictServer extends UDPEcho{
private Map<String,String> map=new HashMap<>();
/**
* 构造方法,完成服务器的初始化
*/
public UDPDictServer(int port) throws Exception {
super(port);
map.put("dog","小狗");
map.put("cat","小猫");
map.put("pig","小猪");
map.put("tiger","大老虎");
map.put("veryGood","牛");
}
public String processor(String request){
return map.getOrDefault(request,"查无此词");
}
public static void main(String[] args) throws Exception {
UDPDictServer server=new UDPDictServer(9999);
server.start();
}
}