本篇续接到应用层及java有关的udp套接字编程
目录
1.应用层协议原理
1.1应用程序体系结构
1.1.1网络应用程序体系结构
客户机-服务器机构
纯对等结构
服务器并非始终在线
任意的终端系统直接进行通信
对等方请求服务,同时也提供服务
自扩展性:对等方加入即增加新的服务需求,也带来新的服务
对等方间歇连接网络,IP地址时常改变
管理的困难性
混合结构
结合了C/S和P2P结构
qq啊迅雷啊这样的
1.1.2进程通信
进程: 运行于主机中的程序
在同一计算机内,两个进程可以使用“进程间通信”来交换信息
在两个不同端系统上的进程通过计算机网络交换报文互相通信
1.1.3套接字(socket)
进程通过套接字发送和接收报文
套接字如同一扇门,发送进程将报文推出“门”
依赖两个“门”间的网络基础设施,将报文送到接收进程的套接字
1.1.4进程寻址
为了让一个进程能接收到报文,必须给它分配一个标识
进程标识符同时包含IP地址和端口号(port number)
端口号用于区分同一个主机上的不同进程
长度16bit
最大端口号65535
常见端口号
1.2应用程序服务需求
1.2.1应用程序服务需求
可靠性 |
某些应用(如音频)可以容忍一些数据丢失 其他一些应用(如, 文件传输)要求数据传输100%的可靠 |
吞吐量 |
一些应用要求保证最低带宽(如多媒体应用) 其他一些应用对带宽没有要求(“弹性应用”) |
定时 |
一些应用(如:网络电话,互动游戏)要求时延很小 |
安全性 |
加密, 数据完整性 |
1.2.2因特网运输层提供的服务
udp和tcp区别反正考试中还是挺常见的
2.Web和HTTP
2.1.1HTTP概括
Web的应用层协议是超文本传输协议(HyperText Transfer Protocol)
由客户程序和服务器程序实现
多数Web页面含有一个HTML基本文件以及几个引用对象。
HTTP定义了Web客户向Web服务器请求页面的方式。
HTTP使用TCP作为他的支撑运输协议
2.1.2非连续性和持续链接
采用非持续连接的HTTP
采用非持续链接的HTTP
2.1.3HTTP报文格式
HTTP请求报文
HTTP响应报文
2.1.4用户与服务器的交互:cookie
3.因特网中的电子邮件
3.1 SMTP
SMTP使用TCP可靠数据传输服务,使用持续连接。用于从发送方的邮件服务器发送报文到接收方的邮件服务器。
3.2 与HTTP的对比
HTTP主要是一个拉协议(pull protocol),SMTP是一个推协议(push protocol)。HTTP把每个对象封装到它自己的HTTP响应报文中,而SMTP把所有报文对象放在一个报文之中。
3.3 邮件报文格式和MIME
邮件包括报文首部和报文体。
3.4 邮件访问协议
3.4.1pop3
是一个非常简单的邮件访问协议
特许 事务处理 更新
3.4.2IAMP
所有消息维持在服务器上,协议支持用户可直接在服务器上操作
3.4.3基于web的电子邮件
用户代理就是普通的浏览器,用户和远程邮箱之间的通信通过HTTP进行
4.DNS
DNS工作机制
域名系统(Domain Name System,DNS)
4.1应用层协议:
主机名到IP地址的转换
客户/服务器体系结构
4.2分布式数据库:
4.2.1层次化结构
4.2.2域名服务器
1、根域名服务器
本地域名服务器不能解析的请求都转发给根服务器 全球 根域名服务器 (13个,A~M
2、顶级域名服务器
负责在 com, net, edu,…等顶级域名和所有国家顶级域名,如 cn, uk, jp。 网络提供商负责维护 com 顶级域名 教育机构维护 edu 顶级域名
3、权威域名服务器
某个组织的 DNS 服务器, 负责自身范围内名字到IP地址的映射 (e.g., Web 和 mail服务器). 由组织和ISP负责维护
4.2.3域名解析
递归查询 迭代查询
主机默认采用递归查询向本地域名服务器发起查询 本地域名服务器采用迭代查询
4.3DNS缓存
DNS缓存
一旦服务器知道了映射关系, 它要缓存映射
缓存内容在一定时间后要过期
本地域名服务器缓存顶级域名服务器的地址 避免频繁访问根域名服务器
DNS记录和报文
5.Socket套接字
5.1概念
5.2分类
5.2.1流套接字
5.2.2数据报套接字
DatagramPacket表示一个UDP数据报
发送一次数据 就是在发一个DatagramPacket
接受一次数据 也就是在收一个DatagramPacket
UDP数据报套接字编程
方法签名
|
方法说明
|
DatagramSocket()
|
创建一个
UDP
数据报套接字的
Socket,绑定到本机任意一个随机端口(一般用于客户端)
|
DatagramSocket(int
port)
|
创建一个
UDP
数据报套接字的
Socket
,绑定到本机指定的端口(一般用
于服务端)
|
DatagramSocket
| |
void
receive(DatagramPacketp)
|
从此套接字接收数据报(如果没有接收到数据报,该方法会阻
塞等待)
|
voidsend(DatagramPacket
p)
|
从此套接字发送数据报包(不会阻塞等待,直接发送)
|
void close()
|
关闭此数据报套接字
|
DatagramPacketAPI
| |
DatagramPacket
是
UDPSocket
发送和接收的数据报。
DatagramPacket 构造方法
| |
方法签名
|
方法说明
|
DatagramPacket(byte[]
buf, int length)
|
构造一个
DatagramPacket
以用来接收数据报,接收的数据保存在
字节数组(第一个参数
buf
)中,接收指定长度(第二个参数
length
)
|
DatagramPacket(byte[]
buf,intoffset,intlength,
SocketAddressaddress)
|
构造一个
DatagramPacket
以用来发送数据报,发送的数据为字节
数组(第一个参数
buf
)中,从
0
到指定长度(第二个参数
length
)。
address
指定目的主机的
IP
和端口号
|
DatagramPacket方法
| |
InetAddress
getAddress()
|
从接收的数据报中,获取发送端主机
IP
地址;或从发送的数据报中,获取
接收端主机
IP
地址
|
int getPort()
|
从接收的数据报中,获取发送端主机的端口号;或从发送的数据报中,获
取接收端主机端口号
|
byte[] getData()
|
获取数据报中的数据
|
构造
UDP
发送的数据报时,需要传入
建。
|
InetSocketAddress
|
(
SocketAddress
的子类)构造方法
|
方法签名
|
方法说明
|
InetSocketAddress(InetAddress addr, int port
|
创建一个
Socket
地址,包含
IP
地址和端口号
|
UdpEchoClient
package network;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Scanner;
public class UdpEchoClient {
private DatagramSocket socket = null;
private String serverIP;
private int serverPort;
// 站在客户端的角度:
// 源 IP: 本机 IP
// 源端口: 系统分配的端口
// 目的 IP: 服务器的 IP
// 目的端口: 服务器的端口
// 协议类型: UDP
public UdpEchoClient(String ip, int port) throws SocketException {
// 此处的 port 是服务器的端口.
// 客户端启动的时候, 不需要给 socket 指定端口. 客户端自己的端口是系统随机分配的~~
socket = new DatagramSocket();
serverIP = ip;
serverPort = port;
}
public void start() throws IOException {
Scanner scanner = new Scanner(System.in);
while (true) {
// 1. 先从控制台读取用户输入的字符串
System.out.print("-> ");
String request = scanner.next();
// 2. 把这个用户输入的内容, 构造成一个 UDP 请求, 并发送.
// 构造的请求里包含两部分信息:
// 1) 数据的内容. request 字符串
// 2) 数据要发给谁~ 服务器的 IP + 端口
DatagramPacket requestPacket = new DatagramPacket(request.getBytes(), request.getBytes().length,
InetAddress.getByName(serverIP), serverPort);
socket.send(requestPacket);
// 3. 从服务器读取响应数据, 并解析
DatagramPacket responsePacket = new DatagramPacket(new byte[1024], 1024);
socket.receive(responsePacket);
String response = new String(responsePacket.getData(), 0, responsePacket.getLength(), "UTF-8");
// 4. 把响应结果显示到控制台上.
System.out.printf("req: %s, resp: %s\n", request, response);
}
}
public static void main(String[] args) throws IOException {
// 由于服务器和客户端在同一个机器上, 使用的 IP 仍然是 127.0.0.1 . 如果是在不同的机器上, 当然就需要更改这里的 IP 了
UdpEchoClient client = new UdpEchoClient("127.0.0.1", 9090);
client.start();
}
}
//早就已经把服务器启动起来来了,启动服务器之后,才开始写客户端代码的 在写客户端代码的这个过程中
//服务早就卡在receive这里阻塞等待了
//58251是随机分配的
//客户端是可以有很多的 一个服务器可以给很多很多客户端提供服务
UdpEchoServer
得先启动服务器
package network;
import com.sun.javaws.jnl.XMLFormat;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class UdpEchoServer {
//
private DatagramSocket socket = null;
public UdpEchoServer(int port) throws SocketException {
socket = new DatagramSocket(port);//此处在构造服务器这边的socket对象的时候,就需要显示的绑定一个端口号
//端口号是用来区分一个应用程序的 主机收到网卡上的数据结构的时候这个数据应该该给哪个程序
}
//启动服务器
public void start() throws IOException {
System.out.println("启动服务器");
//UDP不需要建立连接,直接接受从客户端来的数据即可
while (true){
//1.读取客户端发来的请求
DatagramPacket requestPacket = new DatagramPacket(new byte[1024],1024);
socket.receive(requestPacket);//requestPacket是输出型参数 为了接收数据,需要先准备一个空的DataPacket对象,由receive来进行填充数据
//把DatagramPacket 解析成一个String
String request = new String(requestPacket.getData(), 0,requestPacket.getLength(),"UTF-8");
//2.根据请求计算响应
String response = process(request);
//3.把响应写回客户端
DatagramPacket responsePacket = new DatagramPacket(response.getBytes(), response.getBytes().length,
requestPacket.getSocketAddress());
socket.send(responsePacket);
System.out.printf("[%s:%d] req: %s, resp: %s\n",
requestPacket.getAddress().toString(), requestPacket.getPort(), request, response);
}
}
public String process(String request) {
return request;
}
public static void main(String[] args) throws IOException {
UdpEchoServer server = new UdpEchoServer(9090);
server.start();
}
}