网络通信:
IP地址:IP地址 网络中设备的标识,可以唯一标识一台计算机端口: 用于标识进程的逻辑地址,不同进程的标识
协议: 通讯的规则 常见协议:TCP,UDP
IP地址:ip地址就是一个标识号,是一个32bit的数据。
例如:192.168.1.100
对应的二进制数据是:11000000 10101000 00000001 01100100
也就是说我的ip地址其实是:11000000 10101000 00000001 01100100
如果是这个样子的,那么,记忆就太麻烦了,所以,针对ip地址,我们出现了这样的规则:点分十进制计数法。
IP地址分类:IPV4(32bit),IPV6(128bit)
A类 1.0.0.1---127.255.255.254
(1)10.X.X.X是私有地址(私有地址就是在互联网上不使用,而被用在局域网络中的地址)
(2)127.X.X.X是保留地址,用做循环测试用的。
B类 128.0.0.1---191.255.255.254 172.16.0.0---172.31.255.255是私有地址。169.254.X.X是保留地址。
C类 192.0.0.1---223.255.255.254 192.168.X.X是私有地址
D类 224.0.0.1---239.255.255.254
E类 240.0.0.1---247.255.255.254
IP地址的组成
IP地址 = 网络号码+主机地址
A类IP地址:第一段号码为网络号码,剩下的三段号码为本地计算机的号码 12.x.x.x 256*256*256*127
B类IP地址:前二段号码为网络号码,剩下的二段号码为本地计算机的号码 132.111.x.x 256*256*256
C类IP地址:前三段号码为网络号码,剩下的一段号码为本地计算机的号码 193.23.45.x 256*256
特殊的ip地址:
127.0.0.1 本机
x.x.x.0 网络地址
x.x.x.255 广播地址
命令:
ipconfig 查看ip地址
ping x.x.x.x 检测连接
端口:
逻辑端口 我们指的就是逻辑端口
A:每个网络程序都会至少有一个逻辑端口
B:用于标识进程的逻辑地址,不同进程的标识
C:有效端口:0~65535,其中0~1024系统使用或保留端口。
协议:
通信的规则
UDP:
把数据打包,不建立连接。
不能保证数据全部接收。
速度快。
大小有限制,64k。
64k = 64*1024byte = 64 * 512char = 32768汉字 = 5个小时。
举例:凌波群发数据,QQ群聊
TCP:
建立数据通道,有连接。(面向连接的编程,3次握手协议。)
数据可靠,不会有丢失。
速度慢。
数据没有限制。
举例:QQ聊天(在线单聊),打电话
类InetAddress
A:全部是静态的
B:单例设计模式
C:通过一个静态方法,返回该类的一个对象。
方法:
public static InetAddress getLocalHost():返回本地主机
public static InetAddress getByName(String host):根据指定的主机,返回InetAddress
代码示例:
public class InetAddressDemo {
public static void main(String[] args) throws UnknownHostException {
// 获取本地主机
InetAddress ia = InetAddress.getLocalHost();
String ip = ia.getHostAddress();
String name = ia.getHostName();
System.out.println(ip + "***" + name);
// 获取指定主机
// InetAddress ia2 = InetAddress.getByName("liuyi");
// InetAddress ia2 = InetAddress.getByName("192.168.1.100");
InetAddress ia2 = InetAddress.getByName("ZHANGDONG");
String ip2 = ia2.getHostAddress();
String name2 = ia2.getHostName();
System.out.println(ip2 + "***" + name2);
}
}
sock实现简单聊天:
public class ChatDemo {
public static void main(String[] args) throws IOException {
// 发送端
DatagramSocket sendDs = new DatagramSocket();
// 接收端
DatagramSocket receiveDs = new DatagramSocket(12345);
// 把发送的代码用线程封装
SendThread st = new SendThread(sendDs);
// 把接收的代码用线程封装
ReceiveThread rt = new ReceiveThread(receiveDs);
// 启动线程
Thread t1 = new Thread(st);
Thread t2 = new Thread(rt);
t1.start();
t2.start();
}
}
public class SendThread implements Runnable {
private DatagramSocket ds;
public SendThread(DatagramSocket ds) {
this.ds = ds;
}
@Override
public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(
System.in));
String line = null;
while ((line = br.readLine()) != null) {
if ("886".equals(line)) {
break;
}
// 打包并发送数据
byte[] bys = line.getBytes();
DatagramPacket dp = new DatagramPacket(bys, bys.length,
InetAddress.getByName("192.168.1.255"), 12345);
ds.send(dp);
}
ds.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class ReceiveThread implements Runnable {
private DatagramSocket ds;
public ReceiveThread(DatagramSocket ds) {
this.ds = ds;
}
@Override
public void run() {
try {
while (true) {
// 创建包
byte[] bys = new byte[1024];
DatagramPacket dp = new DatagramPacket(bys, bys.length);
ds.receive(dp);
// 解析数据
String ip = dp.getAddress().getHostAddress();
String data = new String(dp.getData(), 0, dp.getLength());
System.out.println("ip:" + ip + " data:" + data);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}