JAVA网络编程基础
要素
ip地址:ip号和端口号,下面代码用于获取当前ip地址
InetAddress ip4 = Inet4Address.getLocalHost();
System.out.println(ip4.getHostAddress());
通信协议:网络通信协议
网络通信主要使用TCP和UDP
类(包:java.net.InetAddress)
获得ip:InetAddress.getByName
本机 localhost
端口表示计算机上的一个程序的进程:
不同的进程有不同的端口号!用来区分软件
端口范围:0-65535
端口分类:
公有端口:0-1023**(HTTP:80,HTTPS:443,FTP:21,Telent:23)**
程序注册端口:1024-49151**(Tomcat:8080,MySQL:3306,Oracle:1521)**
动态,私有端口:49152-65535
通信协议
tcp/ip协议簇
tcp:用户传输协议
udp:用户数据报协议
使用tcp实现通信(单向,多线程还没学)
客户端代码(注意:关闭资源前要判空,下面代码只判了一个)
public class Client01 {
public static void main(String[] args) {
Socket socket = null;
OutputStream os =null;
try {
//获得服务器的地址和端口号
InetAddress ServerIP = InetAddress.getByName("172.16.6.49");
int port=9999;
//创建一个socket连接
socket = new Socket(ServerIP,port);
//发送信息IO流
os = socket.getOutputStream();
os.write("实验成功,seeyou".getBytes(StandardCharsets.UTF_8));
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
服务端代码
public class server {
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket socket = null;
InputStream is= null;
ByteArrayOutputStream baos = null;
try {
//创建一个socket,端口为9999
serverSocket = new ServerSocket(9999);
//接受客户端的连接
while(true) {
socket = serverSocket.accept();
//读取客户端发送的信息
is = socket.getInputStream();
/*byte[] buffer = new byte[1024];
int len;
while((len=is.read(buffer))!=-1){
String s= new String(buffer,0,len);
System.out.println(s);
}*/
//管道流输出信息
baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
baos.write(buffer, 0, len);
System.out.println(baos.toString());
}
}
} catch (IOException e) {
e.printStackTrace();
}finally {
if(baos!=null) {
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
文件上传
客户端
public class Client02 {
public static void main(String[] args) throws IOException {
//创建一个socket连接
Socket socket = new Socket(InetAddress.getByName("192.168.100.54"), 9000);
//创建一个输出流
OutputStream os = socket.getOutputStream();
//读取文件
FileInputStream fis = new FileInputStream(new File("src/fengxing.png"));
//写出文件
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
//关闭资源,先写后关
fis.close();
os.close();
socket.close();
}
}
服务端
public class server02 {
public static void main(String[] args) throws Exception {
//创建一个服务
ServerSocket serverSocket = new ServerSocket(9000);
//监听客户端的监听
Socket socket = serverSocket.accept();//阻塞式监听,会一直在等待客户端连接
//获取输入流
InputStream is = socket.getInputStream();
//文件输出
FileOutputStream fos = new FileOutputStream(new File("receive.png"));
byte[] buffer = new byte[1024];
int len;
while((len=is.read(buffer))!=-1){
fos.write(buffer,0,len);
}
//关闭资源
fos.close();
is.close();
socket.close();
serverSocket.close();
}
}
UDP
UDP实现简单通信
发送端
* @PackageName:Networks
* @ClassName:UdpClient01
* @Description:使用udp协议进行通信
* @date 2021/8/13 7:44
*/
public class UdpClient01 {
public static void main(String[] args) throws IOException {
//建立一个socket
DatagramSocket socket = new DatagramSocket();
//建立要发送的包
String massage = "我使用了udp找到你了";
InetAddress address = InetAddress.getByName("localhost");
int port = 8081;
//数据包
DatagramPacket packet = new DatagramPacket(massage.getBytes(),0,massage.getBytes().length,address,port);
//发送包
socket.send(packet);
//关闭服务
socket.close();
}
}
接收端
* @PackageName:Networks
* @ClassName:UdpClient02
* @Description:使用udp协议进行通信
* @date 2021/8/13 7:58
*/
public class UdpClient02 {
public static void main(String[] args) throws IOException {
//建立端口
DatagramSocket socket = new DatagramSocket(8081);
//接送数据包
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length);
System.out.println("随时能接受包");
socket.receive(packet);
//打印发来包的主机ip地址
System.out.println(packet.getAddress().getHostAddress());
//打印内容
System.out.println(new String(packet.getData(),0,packet.getLength()));
}
}
UDP实现单向聊天
发送端
* @PackageName:Networks
* @ClassName:UDPchat01
* @Description:使用UDP聊天
* @date 2021/8/13 8:52
*/
public class UDPchat01 {
public static void main(String[] args) throws IOException {
//建立进程端口
DatagramSocket socket = new DatagramSocket(8083);
//从控制台读取数据
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
while (true){
String message =reader.readLine();
//根据控制台输入建立数据包
DatagramPacket packet = new DatagramPacket(message.getBytes(),0,message.getBytes().length,new InetSocketAddress("localhost",8084));
//发送数据包
socket.send(packet);
if (message.equals("bye")) {
break;
}
}
//关闭socket服务
socket.close();
}
}
接收端
* @PackageName:Networks
* @ClassName:UDPchat02
* @Description:
* @date 2021/8/13 8:52
*/
public class UDPchat02 {
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket(8084);
while (true){
//接收包
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length);
socket.receive(packet);//阻塞性接收,需要使用多线程才能实现相互交流
//打印内容
String recive = new String(packet.getData(), 0, packet.getData().length);
System.out.println(packet.getAddress().getHostAddress()+":"+recive);
//需要用trim去掉缓冲区后面的空格,不然bye后面跟着1021个空格,无法正常退出
if (recive.trim().equals("bye")){
break;
}
}
socket.close();
}
}
UDP实现实时通信(终于能玩了)
发送线程
* @PackageName:Networks
* @ClassName:ThreadUDP01
* @Description:发送线程
* @date 2021/8/13 9:50
*/
public class ThreadUDP01 implements Runnable{
//属性
DatagramSocket socket = null;
BufferedReader reader = null;
//目前没啥用
private int fPort;
//目的地
private String toIP;
private int toPort;
//构造函数
public ThreadUDP01(int fPort, String toIP, int toPort) {
this.fPort = fPort;
this.toIP = toIP;
this.toPort = toPort;
try {
//目前没啥用
this.socket = new DatagramSocket(fPort);
//从控制台读取信息
this.reader = new BufferedReader(new InputStreamReader(System.in));
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (true){
try {
//读取控制台一行信息
String message =reader.readLine();
//根据控制台输入建立数据包
DatagramPacket packet = new DatagramPacket(message.getBytes(),0,message.getBytes().length,new InetSocketAddress(toIP,toPort));
//发送数据包
socket.send(packet);
if (message.equals("bye")) {
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
//关闭socket服务
socket.close();
}
}
接收线程
* @PackageName:Networks
* @ClassName:ThreadUDP02
* @Description:接收线程
* @date 2021/8/13 9:50
*/
public class ThreadUDP02 implements Runnable{
//属性
DatagramSocket socket = null;
private int port;
//谁发送的信息,目前是固定写死的,以后可以动态读取
private String fName;
//构造函数
public ThreadUDP02(int port, String fName) {
try {
this.socket = new DatagramSocket(port);
} catch (SocketException e) {
e.printStackTrace();
}
this.port = port;
this.fName = fName;
}
@Override
public void run() {
while (true){
//接收包
try {
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length);
socket.receive(packet);//阻塞性接收,需要使用多线程才能实现相互交流
//打印内容
String recive = new String(packet.getData(), 0, packet.getData().length);
System.out.println(fName+":"+recive);
if (recive.trim().equals("bye")){
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
socket.close();
}
}
学生端与教师端
* @PackageName:Networks
* @ClassName:ChatStudent
* @Description:学生端
* @date 2021/8/15 8:33
*/
public class ChatStudent {
public static void main(String[] args) {
new Thread(new ThreadUDP01(6666,"localhost",8100)).start();
new Thread(new ThreadUDP02(7777,"老师")).start();
}
}
* @PackageName:Networks
* @ClassName:ChatTeacher
* @Description:教师端
* @date 2021/8/15 8:33
*/
public class ChatTeacher {
public static void main(String[] args) {
new Thread(new ThreadUDP01(8200,"localhost",7777)).start();
new Thread(new ThreadUDP02(8100,"学生")).start();
}
}
老师好
老师:你好,有什么问题吗
做个实验,成功了
老师:那就好
bye
老师:bye
Process finished with exit code 0
学生:老师好
你好,有什么问题吗
学生:做个实验,成功了
那就好
学生:bye
bye
Process finished with exit code 0
bye
Process finished with exit code 0