一、通信要素
1、ip和端口号
2、网络通信协议
1.1)IP
java中用InetAddress这个类来表示IP地址
举个例子:
@Test
public void test1(){
InetAddress inetAddress= null;
try {
inetAddress = InetAddress.getByName("www.baidu.com");
System.out.println(inetAddress);
System.out.println(inetAddress.getHostName());
System.out.println(inetAddress.getHostAddress());
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
1.2)端口号:
端口号标识正在计算机上运行的进程
1、不同的进程有不同的端口号
2、被规定为一个16位数的整数0~65535
3、端口号的分类:
3.1)公认端口号:0~1023
3.2)注册端口号:1024~49151
3.3)动态/私有端口号:49151~65535
1.3)网络通信协议
TCP和UDP
TCP和UDP属于传输层的协议
TCP
1、使用TCP协议之前需要先进行TCP连接,形成传输数据通道
2、传输前,采用“三次握手”方式确定是否可建立连接
3、传输完毕之后采用“四次挥手”进行连接释放
应用场景:一般用于打电话
TCP的三次握手和四次挥手
三次握手:
要求发送端和接收端都知道对方能否正常发信息和接收信息:
1、发送端发了一条信息,接收方知道发送方可正常发送信息
2、接收方发送了一条信息,发送方知道接收方可接收和发送信息
3、发送方又发送了一条信息,接收方知道发送方可正常接收信息
四次挥手:
1、发送方发送了一条准备断开连接的信息
2、接收方接收到信息,发送了一条确认信息
3、接收方发送了一条已经断开的信息
4、发送方发送信息确认是否已经断开
UDP
1、不需要建立连接
2、每个数据报的大小限制在64k内
3、不能确保接收方是否可接收到数据,连接不可靠
4、无需释放连接
应用场景:用于视频播放
二、基于Socket的TCP网络编程
IP地址与端口号组成一个网络套接字:Socket
客户端步骤:
1)创建一个socket对象,用于标识ip和端口号(这两者都是服务器端的)
2)创建一个输出流,用于输出数据
3)在输出流中写入数据
4)关闭资源
@Test
public void clientSocket(){
Socket socket=null;
OutputStream outputStream=null;
try {
socket=new Socket("127.0.0.1",8888);
outputStream=socket.getOutputStream();
outputStream.write("hello 我是tcp连接的客户端".getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
clientClose(socket, outputStream);
}
}
服务器端步骤:
1)创建服务器端的ServerSocket,并指明自己的端口号
2)调用accept()接收来自客户端的socket
3)获取输入流
4)读取输入流中的数据
5)关闭资源
@Test
public void serverSocket(){
ServerSocket serverSocket=null;
Socket accept=null;
InputStream inputStream=null;
ByteArrayOutputStream byteArrayOutputStream=null;
try {
serverSocket=new ServerSocket(8888);
accept = serverSocket.accept();
inputStream = accept.getInputStream();
byte[] bytes=new byte[10];
byteArrayOutputStream=new ByteArrayOutputStream();
int len=0;
while ((len=inputStream.read(bytes))!=-1){
// System.out.println(new String(bytes,0,len));
byteArrayOutputStream.write(bytes,0,len);
}
System.out.println(byteArrayOutputStream.toString());
}catch (IOException e){
e.printStackTrace();
}finally {
serverClose(accept, inputStream, byteArrayOutputStream);
}
}
注意:读取时不建议直接用数组读取,因为可能会导致中文乱,因为中文在utf-8中是占据3个字节的,如果数组长度不够,中文就会被切割造成乱码,可使用以下输出流读取。
ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream(Byte[] bytes,int startIndex,int length);
三、基于DatagramSocket的UDP网络编程
类 DatagramSocket 和 DatagramPacket 实现了基于 UDP 协议网络程序
DatagramPacket 对象封装了UDP数据报,在数据报中包含了发送端的IP地址和端口号以及接收端的IP地址和端口号
UDP数据报通过数据报套接字 DatagramSocket 发送和接收,系统不保证
UDP数据报一定能够安全送到目的地,也不能确定什么时候可以抵达
发送端:
@Test
public void sender(){
DatagramSocket datagramSocket=null;
try {
datagramSocket=new DatagramSocket();
byte[] bytes="这是采用udp协议发送的一段文字".getBytes();
DatagramPacket datagramPacket=new DatagramPacket(bytes,0,bytes.length, InetAddress.getLocalHost(),7777);
datagramSocket.send(datagramPacket);
}catch (IOException e){
e.printStackTrace();
}finally {
if (datagramSocket!=null){
datagramSocket.close();
}
}
}
接收端:
@Test
public void receiver(){
DatagramSocket datagramSocket=null;
try {
datagramSocket=new DatagramSocket(7777);
byte[] bytes=new byte[1000];
DatagramPacket datagramPacket=new DatagramPacket(bytes,bytes.length);
datagramSocket.receive(datagramPacket);
System.out.println(new String(datagramPacket.getData(),0,datagramPacket.getLength()));
}catch (IOException e){
e.printStackTrace();
}finally {
if (datagramSocket!=null){
datagramSocket.close();
}
}
}
四、基于HttpURLConnection的Http编程
参考文档:https://blog.csdn.net/woxueliuyun/article/details/43267365