网络通信三要素
通信条件是两个主机通信,这两个主机必须装有相同的通讯协议。
1、 IP地址:网络设备中的标识,用于找到对方IP。不容易记忆,可用主机名。本地回环地址 127.0.0.1 主机名:localhost
2、 端口号:数据发送到对方指定的应用程序上,为了标识这些应用程序,所以给这网络应用程序都用数字标识,称这些数字为端口(逻辑端口)。
用于标识不同进程的逻辑地址,有效端口为:0~65535,其中0~1024为系统使用或保留端口
3、 传输协议:定义通信规则,这个通信规则称为协议。国际组织定义了通用协议TCP/IP。
TCP和UDP
UDP(User Date Protocol)用户数据报协议:
1、将数据封装成数据包中,不需要建立连接
2、每个数据报的大小限制在64k内
3、因无连接,是不可靠协议
4、不需要建立连接,速度快
面向无连接协议,在发送信息时不需要建立连接,在生活中就像到邮局中邮寄包裹一样,只需要知道对方地址即可,是单方面的发送。这样发送的速度很快,但有可能丢掉一些数据包,在线看视屏就是用UDP协议(下载、聊天、视屏会议、桌面共享)。固话机相当于UDP
TCP(Transmission Control Protocol)传输控制协议:
1、 建立连接,形成传输数据的通道
2、 在连接中进行大数据传输
3、 通过三次握手完成连接,是可靠协议
4、 必须建立连接,效率会稍低
打电话就相当于TCP传输
TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接:
位码即tcp标志位,有6种标示:SYN(synchronous建立联机) ACK(acknowledgement 确认) PSH(push传送) FIN(finish结束) RST(reset重置) URG(urgent紧急)
Sequence number(顺序号码) Acknowledge number(确认号码)
第一次握手:主机A发送位码为syn=1,随机产生seq number=1234567的数据包到服务器,主机B由SYN=1知道,A要求建立联机;
第二次握手:主机B收到请求后要确认联机信息,向A发送ack number=(主机A的seq+1),syn=1,ack=1,随机产生seq=7654321的包
第三次握手:主机A收到后检查ack number是否正确,即第一次发送的seq number+1,以及位码ack是否为1,若正确,主机A会再发送ack number=(主机B的seq+1),ack=1,主机B收到后确认seq值与ack=1则连接建立成功。
完成三次握手,主机A与主机B开始传送数据。
网络模型
两台主机之间的通信,就是数据的包装与解包的过程,程序发出数据,经过 应用层—》表示层—》会话层—》传输层—》网络层—》数据连接层—》物理层 的一系列数据包装让后通过网线、光纤、无线网等传送到另一台主机上,然后是解包的过程(与包装相反),最后通过端口识别是用哪个程序来处理这段信息。
传输协议
IP地址:如何获取本机地址
import java.net.InetAddress;
public classTest1 {
public static void main(String[] args) {
InetAddress ia = null;
try {
ia = InetAddress.getLocalHost();
} catch(Exception e) {
System.out.println("err!");
}
//输出主机IP地址
System.out.println(ia.getHostAddress());
//输出主机名
System.out.println(ia.getHostName());
}
}
拿到任何一台主机IP地址getByName(String host)通过主机名获取主机IP地址
如果IP地址和对应的主机名没有在网络上,程序虽然可以找到这个IP地址,但是无法解析成功,则主机名字还是IP地址。
import java.net.InetAddress;
import java.net.UnknownHostException;
public classTest2 {
public static void main(String[] args) throws UnknownHostException {
//获取主机名下的所有IP地址,一个IP地址数组
InetAddress[] i = InetAddress.getAllByName("www.baidu.com");
for(Object o:i){
System.out.println(o);
}
System.out.println();
//获取一个IP地址
InetAddress ip = InetAddress.getByName("www.baidu.com");
System.out.println(ip);
}
}
获取主机名需要解析,还是获取IP地址效率更高一些
Socket网络编程
Socket就是网络服务提供的一种机制
通信的两端都有Socket
网络通信其实就是Socket间的通信
数据在两个Socket之间通过IO传输
1、 通过UDP传输方式,将一段文字数据发送出去
a) 建立UDP的Socket服务
b) 提供数据,并将数据封装到数据包中
c) 通过Socket服务的发送功能,将数据包发送出去
d) 关闭资源
import java.net.*;
public classSocketTest {
public void go() throws Exception {
//创建UDP服务,指定端口为8888
DatagramSocket ds = newDatagramSocket(8888);
//创建并封装数据报
byte[] buf = "forever not along".getBytes();
InetAddress i = InetAddress.getByName("127.0.0.1");
DatagramPacket dp = newDatagramPacket(buf, buf.length,i,55555);
try {
//发送数据
ds.send(dp);
System.out.println("发送成功!");
} catch(Exception e) {
System.out.println("发送失败!");
} finally{
System.out.println("关闭系统资源");
ds.close();
}
}
public static void main(String[] args) throws Exception {
SocketTest st = newSocketTest();
st.go();
}
}
2、 UDP接收端
a) 建立UDP服务
b) 定义一个数据包,用来存储接收到的字节数据,因为数据包对象中有更多功能可以提取字节数据中的不同数据信息
c) 通过Socket服务的receive方法将接受到的数据存入已定义好的数据包中
d) 通过数据包对象的特有功能,将这些不同的数据去除
e) 关闭资源
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public classUdpReceive {
public static void main(String[] args) throws Exception{
//定义UDP的Socket服务
DatagramSocket ds = newDatagramSocket(55555);
//定义一个数组缓存
byte[] buf = new byte[1024];
//定义接收数据包
DatagramPacket dp = newDatagramPacket(buf, buf.length);
ds.receive(dp);
//通过数据包的方法获取数据
String ip = dp.getAddress().getHostAddress();
System.out.println(ip);
String str = newString(dp.getData(),0,dp.getLength());
System.out.println(str);
int port = dp.getPort();
System.out.println(port);
ds.close();
}
} |
|