InetAddress类
public static InetAddressgetByName(String host):
(其他获取InetAddress对象的方法参考api手册)
根据主机名或者IP地址的字符串表示得到IP地址对象
主机名:public String getHostName()
IP地址public String getHostAddress()
端口
物理端口 网卡口 逻辑端口 我们指的就是逻辑端口 A:每个网络程序都会至少有一个逻辑端口 B:用于标识进程的逻辑地址,不同进程的标识 C:有效端口:0~65535,其中0~1024系统使用或保留端口。 通过360可以查看端口号协议:
通信的规则 UDP: 把数据打包 数据有限制 不建立连接 速度快 不可靠 TCP: 建立连接通道 数据无限制 速度慢 可靠协议UDP和TCP
UDP 将数据源和目的封装成数据包中,不需要建立连接;每个数据报的大小在限制在64k;因无连接,是不可靠协议;不需要建立连接,速度快 TCP 建立连接,形成传输数据的通道;在连接中进行大数据量传输;通过三次握手完成连接,是可靠协议;必须建立连接,效率会稍低Socket
Socket套接字: 网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标识符套接字。 Socket原理机制: 通信的两端都有Socket。 网络通信其实就是Socket间的通信。 数据在两个Socket间通过IO传输。Udp发送端代码
/*
* UDP协议发送数据:
* A:创建发送端Socket对象
* B:创建数据,并把数据打包
* C:调用Socket对象的发送方法发送数据包
* D:释放资源
*/
DatagramSocket ds = new DatagramSocket();
创建数据,并把数据打包
// DatagramPacket(byte[] buf, int length, InetAddress address,int port)
// 创建数据
byte[] bys = "hello,world".getBytes();
// 长度
int length = bys.length;
// IP地址对象
InetAddress address =InetAddress.getByName("192.168.12.92");
// 端口
int port = 10086;
DatagramPacket dp = new DatagramPacket(bys, length, address, port);
// 调用Socket对象的发送方法发送数据包
// public void send(DatagramPacket p)
ds.send(dp);
Udp接收端代码
/*
* UDP协议接收数据:
* A:创建接收端Socket对象
* B:创建一个数据包(接收容器)
* C:调用Socket对象的接收方法接收数据
* D:解析数据包,并显示在控制台
* E:释放资源
// 创建接收端Socket对象
// DatagramSocket(int port)
DatagramSocket ds = new DatagramSocket(10086);
// 创建一个数据包(接收容器)
// DatagramPacket(byte[] buf, int length)
byte[] bys = new byte[1024];
int length = bys.length;
DatagramPacket dp = new DatagramPacket(bys, length);
// 调用Socket对象的接收方法接收数据
// public void receive(DatagramPacket p)
ds.receive(dp); // 阻塞式
// 解析数据包,并显示在控制台
// 获取对方的ip
// public InetAddress getAddress()
InetAddress address =dp.getAddress();
String ip =address.getHostAddress();
// public byte[] getData():获取数据缓冲区
// public int getLength():获取数据的实际长度
byte[] bys2 = dp.getData();
int len = dp.getLength();
String s = new String(bys2, 0, len);
System.out.println(ip + "传递的数据是:" + s)
TCP传输
Socket和ServerSocket 建立客户端和服务器端 建立连接后,通过Socket中的IO流进行数据的传输 关闭socket 同样,客户端与服务器端是两个独立的应用程序。客户端代码
/*
* TCP协议发送数据:
* A:创建发送端的Socket对象
* 这一步如果成功,就说明连接已经建立成功了。
* B:获取输出流,写数据
* C:释放资源
*
* 连接被拒绝。TCP协议一定要先看服务器。
*java.net.ConnectException: Connection refused: connect
*/
// 创建发送端的Socket对象
// Socket(InetAddress address, int port)
// Socket(String host, int port)
// Socket s = newSocket(InetAddress.getByName("192.168.12.92"), 8888);
Socket s = new Socket("192.168.12.92", 8888);
// 获取输出流,写数据
// public OutputStream getOutputStream()
OutputStream os =s.getOutputStream();
os.write("hello,tcp,我来了".getBytes());
// 释放资源
s.close();
服务器代码
/*
* TCP协议接收数据:
* A:创建接收端的Socket对象
* B:监听客户端连接。返回一个对应的Socket对象
* C:获取输入流,读取数据显示在控制台
* D:释放资源
*/
// 创建接收端的Socket对象
// ServerSocket(int port)
ServerSocket ss = new ServerSocket(8888);
// 监听客户端连接。返回一个对应的Socket对象
// public Socket accept()
Socket s = ss.accept(); // 侦听并接受到此套接字的连接。此方法在连接传入之前一直阻塞。
// 获取输入流,读取数据显示在控制台
InputStream is =s.getInputStream();
byte[] bys = new byte[1024];
int len = is.read(bys); // 阻塞式方法
String str = new String(bys, 0, len);
String ip =s.getInetAddress().getHostAddress();
System.out.println(ip + "---" + str);
// 释放资源
s.close();
怎样告诉对方发送完毕
/*
* 正常情况下,如果连接不中断的时,接收信息的一方不会自己判断是否读完,所以会一直处于等待读信息状态,因此需要发送方告知读完的信息,socket的shutdownOuput()方法用于告知对方发送结束。
* public void shutdownOutput()
*/