一.基本概念
1. 源Ip地址和目的Ip地址
和发微信消息一样,小明要给小红发送消息,源Ip指的就是他自己,目的Ip就是
小红,网络通信时候,需要知道这个'消息'是谁发送的,要发给谁。
1.IP源(IP Source)是这个IP数据包从哪里出发、传播的。
2.目的地(IP Destination)是这个数据包所要到达的数据包地点。
在IP数据包头部中, 有两个IP地址, 分别叫做源IP地址, 和目的IP地址.
2.端口号
端口号(port)是传输层协议的内容.
- 端口号是一个32位的整数;
- 端口号用来标识一个进程, 告诉操作系统, 当前的这个数据要交给哪一个进程
来处理;
- IP地址 + 端口号能够标识网络上的某一台主机的某一个进程;
一个端口号只能被一个进程占用.
.端口范围划分
(1)0~1023:知名端口号,是留着备用的,一把都是用于协议,例如HTTP、FTP、SSH
(2)1024~65535:是操作系统动态分配的端口号,客户端程序的端口号,就是由操作糸统从这个范围来分配的,在TCP与UDP的套接字通信中,客户端的端口号就是在此范围中
一个进程可以绑定多个端口号,但是一个端口号只能被一个进程绑定
3.源端口号和目的端口号
传输层协议(TCP和UDP)的数据段中有两个端口号, 分别叫做源端口号和目的端口
号.就是在描述 "数据是谁发的, 要发给谁";
二.认识TCP 和UDP协议
1.TCP协议
- 传输层协议
- 有连接
- 可靠传输
- 面向字节流
2.UDP协议
- 传输层协议
- 无连接
- 不可靠
- 面向数据报
三.Socket接口
1.DataSourcesSocket类
| 方法 | 说明 |
|---|---|
| DatagramSocket(int port,InetAddress laddr) | 创建一个数据报套接字,绑定到指定的本地地址 |
| DatagramSocket(SocketAddress bindaddr) | 创建一个数据报套接字,绑定到指定的本地套接字地址 |
| void bind(SocketAddress addr) | 将此DatagramSocket绑定到特定的地址和端口 |
| void connect(InetAddress address, int port) | 将套接字连接到此套接字的远程地址 |
| void receive(DatagramPacket p) | 从此套接字接收数据报包 |
| void send(DatagramPacket p) | 从此套接字发送数据报包 |
实现一个简单的UDP服务端
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class UdpEchoServer {
// 对于一个服务器程序来说, 核心流程分成两步.
// 1. 进行初始化操作 (实例化 Socket 对象)
// 2. 进入主循环, 接受并处理请求. (主循环就是一个 "死循环")
// a) 读取数据并解析
// b) 根据请求计算响应
// c) 把响应结果写回到客户端.
DatagramSocket socket=null;
UdpEchoServer(int port) throws SocketException {
//当不传入Ip是会默认给定一个特殊的0.0.0.0 ip
//服务器必须绑定端口号
socket=new DatagramSocket(port);
}
public void start() throws IOException {
System.out.println("服务器启动");
while(true){
//读取请求并解析
DatagramPacket requestPacket=new DatagramPacket(new byte[4096],4096);
//尝试从网卡中读数据,如果没有数据,就阻塞
socket.receive(requestPacket);
//获取请求信息
String request=new String(requestPacket.getData(),0,requestPacket.getLength()).trim();
String response=process(request);
DatagramPacket responsePacket=new DatagramPacket(response.getBytes(),
request.getBytes().length,
requestPacket.getSocketAddress());
socket.send(requestPacket);
System.out.printf("[%s:%d] req: %s; resp: %s\n", requestPacket.getAddress().toString(),
requestPacket.getPort(), request, response);
}
}
//为后期不同需求的服务器做准备
private String process(String request) {
return request;
}
public static void main(String[] args) throws IOException {
UdpEchoServer udpEchoServer=new UdpEchoServer(9090);
udpEchoServer.start();
}
}
客户端:
package java40_1124;
import java.io.IOException;
import java.net.*;
import java.util.Scanner;
// 客户端的主要流程分成四步.
// 1. 从用户这里读取输入的数据.
// 2. 构造请求发送给服务器
// 3. 从服务器读取响应
// 4. 把响应写回给客户端.
public class UdpEchoClient {
DatagramSocket socket=null;
private int severPort;
private String severIp;
// 需要在启动客户端的时候来指定需要连接哪个服务器
UdpEchoClient(String severIp,int severPort) throws SocketException {
this.severIp=severIp;
this.severPort=severPort;
//不需要指定端口号 在运行的时候操作系统会自动的分配一个端口号
//为什么不需要指定端口号?
//一个端口号同常情况下只能被一个进程绑定
//如果客户端绑定了的话,那么一个主机就只能运行一个客户端了
socket=new DatagramSocket();
}
public void start() throws IOException {
while (true) {
Scanner scanner=new Scanner(System.in);
System.out.print("->");
String request=scanner.nextLine();
if(request.equals("exit")){
break;
}
DatagramPacket requestPacket=new DatagramPacket(request.getBytes(),request.getBytes().length,
InetAddress.getByName(severIp),severPort);
//向服务器发送请求
socket.send(requestPacket);
//从服务器获取响应
DatagramPacket responsePacket=new DatagramPacket(new byte[4096],4096);
socket.receive(responsePacket);
String response=new String(responsePacket.getData(),0,responsePacket.getLength()).trim();
System.out.println(response);
}
}
public static void main(String[] args) throws IOException {
UdpEchoClient udpEchoClient=new UdpEchoClient("127.0.0.1",9090);
udpEchoClient.start();
}
}
本文介绍了网络编程的基本概念,包括源IP地址、目的IP地址和端口号,并详细讲解了TCP和UDP协议的区别。TCP提供的是有连接、可靠传输的面向字节流服务,而UDP则是无连接、不可靠的面向数据报服务。此外,还提到了Socket接口中的DataSourcesSocket类在实现UDP服务端中的应用。

9803

被折叠的 条评论
为什么被折叠?



