网卡
物理端口
网卡口
逻辑端口
我们指的就是逻辑端口
1、每个网络程序都会至少有一个逻辑端口
2、用于表示进程的逻辑地址,不同进程的标识
3、有效端口:0~65535,其中0~1024系统使用或保留端口
通过netstat -ano可以查看端口号
协议UDP和TCP
Socket
Socket套接字
网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标识符套接字
Socket原理机制
通信的两端都有Socket
网络通信其实就是Socket间的通信
数据在两个Socket间通过IO传输
UDP
将数据源和目的封装成数据包中,不需要建立连接;每个数据报包的大小在限制在64k;因无连接,是不可靠协议;不需要建立连接,速度快
UDP协议发送数据
1、建立发送端的Socket对象
2、创建数据,并将数据打包
3、通过调用Socket的发送方法将数据包发出去
4、释放资源,关闭Socket
public class UDPSend {
public static void main(String[] args) throws Exception{
//建立UDP发送端的Socket对象DatagramSocket
//DatagramSocket()
//构造数据报套接字并将其绑定到本地主机上的任何可用端口
DatagramSocket dgs = new DatagramSocket();
//创建数据,转成字节数据
byte[] data="你好,世界!".getBytes();
//获取字节数组的长度
int length = data.length;
//指定发送端的IP地址
InetAddress inetAddress = InetAddress.getByName("192.168.137.1");
//端口号
//有效端口:0~65535,其中0~1024系统使用或保留端口
int port=8081;
//创建数据包
//DatagramPacket(byte[] buf,int length,InetAddress address,int port)
//构造用于发送长度的分组的数据报包
DatagramPacket dgp = new DatagramPacket(data, length, inetAddress, port);
//void send(DatagramPacket p)
//从此套接字发送数据报包
dgs.send(dgp);
dgs.close();
}
}
UDP接收端接受数据
1、创建接收端的Socket对象
2、创建一个接收包(接受数据容器)
3、调用Socket的接收方法接收数据 receive()
4、解析数据包,获取数据,显示在控制台
5、释放资源,关闭Socket
public class UDPReceive {
public static void main(String[] args) throws Exception{
//创建接收端的Socket对象
//DatagramSocket(int port)
//构造数据报套接字并将其绑定到本地主机上的指定端口
DatagramSocket dgs = new DatagramSocket(8081);
//指定可以接收的字节数组大小
byte[] bytes = new byte[1024];
int length = bytes.length;
//DatagramPacket(byte[] but,int length)
//构造一个DatagramPacket用于接收长度的数据报length
DatagramPacket dgp = new DatagramPacket(bytes, length);
//调用Socket的接收方法接收数据 receive()
//public void receive(DatagramPacket p)
//从此套接字接收数据报包
//该方法阻塞,知道接收到数据包
dgs.receive(dgp);
//分析数据包,获取数据,显示在控制台
//public byte[] getData()返回数据缓冲区
//收到的数据或要发送的数据从缓冲区中的offset开始,运行时间为length
byte[] data = dgp.getData();
String s = new String(data, 0, data.length);
//public InetAddress getAddress()
//返回该数据报发送或接收数据报的计算机的IP地址
System.out.println(dgp.getAddress()+"--"+dgp.getPort()+":"+s);
dgs.close();
//释放资源,关闭Socket
}
}
TCP
建立连接,形成传输数据的通道;在连接中进行大数据量传输;通过三次握手完成连接连接,是可靠协议;必须建立连接,效率会稍低
实现思想:
Socket和ServerSocket
建立客户端和服务器
建立连接后,通过Socket中的IO流进行数据的传输
关闭socket
同样,客户端和服务器端是两个独立的应用程序
TCP传输-客户端思路
1、建立客户端的Socket服务,并明确要连接的服务器
2、如果连接建立成功,就表名,已经建立了数据传输的通道,就可以在该通道通过IO进行数据的读取和写入。该通道称为Socket流,Socket流中既有读取流,也有写入流
3、通过Socket对象的方法,可以获取这两个流
4、通过流的对象可以对数据进行传输
5、如果传输数据完毕,关闭资源
public class TCPClient {
public static void main(String[] args) throws Exception{
//创建发送端的Socket对象
//Socket(InetAddress address,int port)
//创建流套接字并将其连接到指定IP地址的指定端口号
//Socket s=new Socket(InetAddress.getByName("192.168.3.104"),12345)
//Socket(String host,int port)
//创建流套接字并将其连接到指定主机上的指定端口号
Socket client = new Socket("192.168.137.1",8080);
//获取输出流
//OutputStream getOutputStream()
//返回此套接字的输出流
OutputStream os = client.getOutputStream();
os.write("你好,世界!".getBytes());
//释放资源
client.close();
}
}
TCP传输-服务器端思路
1、建立服务器端的socket服务,需要一个端口
2、服务端没有直接流的操作,而是通过accept方法获取客户端对象,在通过获取到的客户端对象的流和客户端进行通信
3、通过客户端的获取流对象的方法,读取数据或者写入数据
4、如果服务完成,需要关闭客户端,然后关闭服务器,但是,一般会关闭客户端,不会关闭服务器,因为服务端是一直提供服务的
public class TCPService {
public static void main(String[] args) throws Exception{
//创建接收端的Socket对象
ServerSocket ss = new ServerSocket(8080);
//监听客户端连接,返回 一个对应的Socket对象
//Socket accept()
//倾听要连接到此套接字并接受它
Socket accept = ss.accept(); //该方法将阻塞直到建立连接
//获取输入流,读取数据显示在控制台
InputStream is = accept.getInputStream();
byte[] bytes = new byte[1024];
int length = bytes.length;
int read = is.read(bytes);
String s = new String(bytes, 0, length);
System.out.println(accept.getInetAddress()+":"+s);
//释放资源
ss.close();
}
}