Java--网络编程(一)
一.Socket套接字
Socket是一种通信机制,允许不同机器上的进程通过网络进行数据交换,他是应用层与传输层之间的桥梁,封装了TCP/IP族协议的细节
针对传输层协议分为三类:
1.流套接字:使用传输层TCP协议(Transmission Control Protocol)
特点:有连接,可靠传输,面向字节流
2.数据报套接字:使用传输层UDP协议(User Datagram Protocol)
特点:无连接,不可靠传输,面向数据报
3.原始套接字(不重要):⽤于⾃定义传输层协议,⽤于读写内核没有处理的IP协议数据
二..数据报套接字
在Java中,主要用 DatagramSocket 类来创建数字报套接字
DatagramSocket 构造方法:
1.无参
DatagramSocket socket = new DatagramSocket();
这种构造方法系统会自动分配一个端口号,适用于客户端和不需要固定端口的服务端。
2.固定端口号
DatagramSocket socket = new DatagramSocket(7721);
这种构造方法由程序员指定分配一个端口号,适用于服务端。
DatagramSocket相关方法:
1.void receive(DatagramPacket p)
用来接收数据报,如果没有接收到数据报,会进行阻塞等待。
2.void send(DatagramPacket p)
用来发送数据报(直接发送,不会阻塞等待)
3.void close
关闭数据包套接字
DatagramPacket
DatagramParket 是用来处理 UDP 数据的核心类
主要作用:
数据封装:将要发送或接收的数据打包成UDP数据包格式
地址管理:存储目标或源地址信息(IP地址和端口号)
缓冲区管理:管理数据的字节缓冲区
接收数据报构造方法:
1.DatagramPacket(byte[] buf,int length)
buf :数据缓冲区,用于临时存放要发送的字节数据
length :缓冲区长度
2.DatagramPacket(byte[] buf,int offset,int length)
offset:缓冲区起始偏移量(offset 就是相当于数据的起始位置)
发送数据报的构造方法:
1.DatagramPacket(byte[] buf,int length,IntAddress address,int port)
address : 目标IP地址
port : 目标端口号
2.DatagramPacket(byte[] buf,int offset,int length,IntAddress address,int port)
DatagramPacket 相关方法:
IntAddress getAddress():
从接收的数据报中获取发送端主机的IP地址
int getPart():
从接收的数据报中获取发送端主机的端口号
byte[] getData():
获取数据报中的数据
IntSocketAddress:
SocketAddress 主要通过 IntSocketAddress 来构建。发送数据包的构建方法里面要用到SocketAddress
IntSocketAddress 构造方法
1.IntSocketAddress(IntAddress addr,int port)
addr:主机IP地址
port:端口号
实例代码演示:
UDP Echo Server : 服务端
import java.io.IOException;
import java.net.*;public class EdpChoServe {private DatagramSocket socket = null;public EdpChoServe(int port) throws SocketException {socket = new DatagramSocket(port);}public void start() throws IOException {System.out.println("服务器启动");while (true){//创建接收缓冲区DatagramPacketDatagramPacket requestparcket = new DatagramPacket(new byte[1024],1024);//接收客户端数据socket.receive(requestparcket);//将数据转化为字符串类型String request = new String(requestparcket.getData(),0, requestparcket.getLength());//将转化后的数据通过process方法进行处理(此处直接返回,如果要进行相关数据的处理直接修改process方法)String response = process(request);//再次创建DatagramPacket套接字,将加工的数据给客户端发送DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,requestparcket.getSocketAddress());//发送数据socket.send(responsePacket);//打印客户端地址,端口,请求和相应信息System.out.printf("[%s:%d] req:%s,resp:%s\n",requestparcket.getAddress().toString(),requestparcket.getPort(),request,response);}}private String process(String request){String response = "服务端返回的消息:"+request;return response;}public static void main(String[] args) throws IOException {EdpChoServe serve = new EdpChoServe(1010);serve.start();}
}
UDP Echo Client: 客户端
import java.io.IOException;
import java.net.*;
import java.util.Scanner;public class EdpChoClient {private DatagramSocket socket = null;private String IP;private int Port;public EdpChoClient(String ip,int port) throws SocketException {socket = new DatagramSocket();this.IP = ip;this.Port = port;}public void start() throws IOException {System.out.println("客户端启动");Scanner scanner = new Scanner(System.in);while (true){//输入要传输的内容String request = scanner.next();//创建DatagramPacket来储存数据 字节数组,数组长度,IP地址和端口号DatagramPacket requestpacket = new DatagramPacket(request.getBytes(),request.getBytes().length, InetAddress.getByName(this.IP),this.Port);//发送数据socket.send(requestpacket);DatagramPacket responsePacket = new DatagramPacket(new byte[1024],1024);//接收客户端处理后的消息socket.receive(responsePacket);//转化为 String 类型String response = new String(responsePacket.getData(),0,responsePacket.getLength());//打印System.out.println(response);}}public static void main(String[] args) throws IOException {EdpChoClient client = new EdpChoClient("127.0.0.1",1010);client.start();}
}