Socket网络编程
网络编程概述
1.1 IP地址(InetAddress类)
- 每台网络终端在网络中都有一个独立的地址,我们在网络中传输数据就是使用这个地址。
- ipconfig:查看本机IP
- ping:测试连接
- 本地回路地址:127.0.0.1
- IPv4:4个字节组成,4个0-255。大概42亿,30亿都在北美,亚洲4亿。已经用尽。0000.0000.0000.0000-1111.1111.1111.1111
- IPv6:8组,每组4个16进制数。
1.2 端口号
- 每个网络程序都需要绑定一个端口号,传输数据的时候除了确定发到哪台机器上,还要明确发到哪个程序。
- 端口号范围从0-65535
- 编写网络应用就需要绑定一个端口号,尽量使用1024以上的,1024以下的基本上都被系统程序占用了。
- 常用端口
- mysql: 3306
- oracle: 1521
- web: 80
- tomcat: 8080
- QQ: 4000
1.3 网络协议
为计算机网络中进行数据交换而建立的规则、标准或约定的集合。
java.net包中J2SE的 API 包含有类和接口,它们提供低层次的通信细节。你可以直接使用这些类和接口,来专注于解决问题,而不用关注通信细节。
java.net
包中提供了两种常见的网络协议的支持:
- UDP
- 面向无连接,数据不安全,速度快。不区分客户端与服务端。
- TCP
- 面向连接(三次握手),数据安全,速度略低。分为客户端和服务端。
1.4 Socket
- 通信的两端都有Socket。
- 网络通信其实就是Socket间的通信。
- 数据在两个Socket间通过IO传输。
- Socket在应用程序中创建,通过一种绑定机制与驱动程序建立关系,告诉自己所对应的IP和port。
UDP传输
2.1 发送
- 创建DatagramSocket
- 创建DatagramPacket
- 使用DatagramSocket发送DatagramPacket
- 关闭DatagramSocket
//发送端
public class UdpTalkClient {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(8989);
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(System.in));
String s = bufferedReader.readLine();
byte[] bytes=s.getBytes();
DatagramPacket datagramPacket = new DatagramPacket(bytes,0,bytes.length,new InetSocketAddress("localhost",6666));
socket.send(datagramPacket);
socket.close();
}
}
2.2 接收
- 创建DatagramSocket
- 创建DatagramPacket
- 使用DatagramSocket接收DatagramPacket
- 关闭DatagramSocket
public class UdpTalkServer {
public static void main(String[] args) throws Exception {
DatagramSocket datagramSocket = new DatagramSocket(6666);
byte[] bytes=new byte[1024*60];
DatagramPacket packet = new DatagramPacket(bytes,0,bytes.length);
datagramSocket.receive(packet);
byte[] data = packet.getData();
System.out.println(new String(data));
}
}
3. TCP传输
3.1 客户端
- 创建Socket连接服务端
- 调用Socket的getInputStream()和getOutputStream()方法获取和服务端相连的管道流
- 输入流可以读取服务端输出流写出的数据
- 输出流可以写出数据到服务端的输入流
/*网络编程 (socket编程)
* tcp(理解为打电话)和udp(理解为写信)是数据层的
* http是应用层的,底层的实现还是用tcp和udp
*
* */
/* 创建客户端
* 1.创建一个套接字并将其连到指定远程地址的指定远程端口
* 2. 操作 输入输出流
* 3. 释放资源
*
* */
import java.io.*;
import java.net.Socket;
public class Client {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("localhost", 8888);
DataOutputStream outputStream= new DataOutputStream(socket.getOutputStream());
String str="世界你好,请善良待我";
outputStream.writeUTF(str);
outputStream.flush();
outputStream.close();
socket.close();
}
}
3.2 服务端
- 创建ServerSocket
- 调用ServerSocket的accept()方法接收一个客户端请求,得到一个Socket
- 调用Socket的getInputStream()和getOutputStream()方法获取和客户端相连的管道流
- 输入流可以读取客户端输出流写出的数据
- 输出流可以写出数据到客户端的输入流
/* 创建服务器
* 1.创建绑定到特定服务器端口的套字节
* 2.阻塞式等待连接 accept()
* 3.操作:输入输出流
* 4.释放资源
* */
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8888);
Socket accept = serverSocket.accept();
System.out.println("---创建一个客户端连接-------");
DataInputStream inputStream = new DataInputStream(accept.getInputStream());
String s = inputStream.readUTF();
System.out.println(s);
inputStream.close();
}
}