说不上技术分享,只能算是学习记录
网络编程
java.net 包中提供了两种常见的网络协议的支持:
- TCP:TCP(英语:Transmission Control
Protocol,传输控制协议)
是一种面向连接的、可靠的、基于字节流的传输层通信协议,TCP 层是位于 IP
层之上,应用层之下的中间层。TCP
保障了两个应用程序之间的可靠通信。通常用于互联网协议,被称 TCP /
IP。
- UDP:UDP (英语:User Datagram
Protocol,用户数据报协议),位于 OSI
模型的传输层。一个无连接的协议。提供了应用程序之间要发送数据的数据报。由于UDP缺乏可靠性且属于无连接协议,所以应用程序通常必须容许一些丢失、错误或重复的数据包。
本教程主要讲解以下两个主题。
- Socket
编程:这是使用最广泛的网络概念,它已被解释地非常详细。
- URL
处理:这部分会在另外的篇幅里讲,点击这里更详细地了解在 Java
语言中的 URL 处理。
案例:
模板
1.客户端建立连接 ;服务端准备服务(ip[默认本机]:端口)
2.通过socket生成inputstream/outputstream(准备发送数据)
3.使用inputstream/outputstream进行发送、接受数据
4.关闭inputstream/outputstream、socket
服务端(ServerSocket)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| import java.io.*; import java.net.ServerSocket; import java.net.Socket;
public class MyServer { public static void main(String[] args) { ServerSocket serverSocket = null; Socket socket = null; InputStream in = null; BufferedReader reader = null; OutputStream out = null; try { serverSocket = new ServerSocket(8888); System.out.println("服务端启动"); socket = serverSocket.accept(); System.out.println("服务端检测到客户端链接成功!");
in = socket.getInputStream(); reader = new BufferedReader(new InputStreamReader(in)); String info = null; while ((info = reader.readLine()) != null) { System.out.println("I am server,接受到客户端信息是:" + info); } socket.shutdownInput(); out = socket.getOutputStream(); out.write("welcome client....".getBytes()); socket.shutdownOutput(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (reader != null) reader.close(); if (out != null) out.close(); if (in != null) in.close(); if (socket != null) socket.close(); if (serverSocket != null) serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } } } }
|
客户端(Socket)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| import java.io.*; import java.net.Socket;
public class MyClient { public static void main(String[] args) { Socket socket = null ; OutputStream out = null ; InputStream in = null ; BufferedReader reader = null ; try { socket=new Socket("127.0.0.1",8888); System.out.println("客户端链接成功!"); out = socket.getOutputStream(); out.write( "hello server".getBytes() ); socket.shutdownOutput();
in = socket.getInputStream(); reader = new BufferedReader(new InputStreamReader(in)); String info = null; while( (info=reader.readLine()) != null ){ System.out.println("I am client,接收到的服务端消息:"+info); }
socket.shutdownInput(); } catch (IOException e) { e.printStackTrace(); }finally{ try { if(out!=null) out.close(); if(in!=null) in.close(); if(socket!=null) socket.close(); } catch (IOException e) { e.printStackTrace(); }
} } }
|
对象流
网络传递一个对象: 1.将要传递的对象序列化
2.使用对象流(ObjectInputStream/ObjectOutputStream)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| import java.io.Serializable;
public class Student implements Serializable { private int sid ; private String sname ; private int age ;
public Student(){
} public Student(int sid, String sname, int age) { this.sid = sid; this.sname = sname; this.age = age; }
public int getSid() { return sid; }
public void setSid(int sid) { this.sid = sid; }
public String getSname() { return sname; }
public void setSname(String sname) { this.sname = sname; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
@Override public String toString() { return "Student{" + "sid=" + sid + ", sname='" + sname + '\'' + ", age=" + age + '}'; } }
|
服务端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.net.ServerSocket; import java.net.Socket;
public class MyServer { public static void main(String[] args) { ServerSocket serverScoket = null ; Socket socket = null ; InputStream in = null ; ObjectInputStream ois = null ; try { serverScoket = new ServerSocket( 8888) ; socket = serverScoket.accept();
in = socket.getInputStream(); ois = new ObjectInputStream(in); try { Student student = (Student)ois.readObject(); System.out.println(student); socket.shutdownInput(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } catch (IOException e) { e.printStackTrace(); }finally{ try { if(ois!=null) ois.close(); if(in!=null) in.close(); if(socket!=null) socket.close(); if(serverScoket!=null) serverScoket.close(); } catch (IOException e) { e.printStackTrace(); } } } }
|
客户端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| import java.io.IOException; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.net.Socket;
public class MyClient { public static void main(String[] args) { Socket socket = null ; OutputStream out = null ; ObjectOutputStream oos = null ; try { socket = new Socket("localhost",8888) ;
Student student = new Student(1001,"zs",23);
out = socket.getOutputStream(); oos = new ObjectOutputStream(out) ; oos.writeObject( student ); socket.shutdownOutput();
} catch (IOException e) { e.printStackTrace(); } finally{ try { if(oos!=null) oos.close(); if(out!=null) out.close(); if(socket!=null) socket.close(); }catch (IOException e) { e.printStackTrace(); } } } }
|
多客户端问题
思路:客户端代码不变;服务端:每当有一个客户端,就开启一个新线程去处理(每个线程专门处理一个客户端对象)。
服务端线程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| import java.io.*; import java.net.Socket;
public class ServerThread extends Thread{
Socket socket; public ServerThread(Socket socket){ this.socket = socket; }
@Override public void run() { InputStream in =null ; ObjectInputStream ois = null ; OutputStream out = null ; try { in = socket.getInputStream(); ois = new ObjectInputStream(in) ; Student student = (Student)ois.readObject() ; System.out.println(student); socket.shutdownInput();
out = socket.getOutputStream(); out.write("已收到....".getBytes());
} catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { try { out.close(); ois.close(); in.close(); socket.close(); ; } catch (IOException e) { e.printStackTrace(); } } } }
|
服务端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import java.io.IOException; import java.net.ServerSocket; import java.net.Socket;
public class MyServer { public static void main(String[] args) { try { ServerSocket serverSocket = new ServerSocket(8888) ;
while(true) { Socket socket = serverSocket.accept(); ServerThread serverThread = new ServerThread(socket) ; serverThread.start(); }
} catch (IOException e) { e.printStackTrace(); } } }
|
客户端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| import java.io.IOException; import java.io.InputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.net.Socket;
public class MyClient { public static void main(String[] args) { Socket socket = null ; OutputStream out = null ; ObjectOutputStream oos = null ; try { socket = new Socket("localhost",8888) ;
Student student = new Student(1001,"zs",23);
out = socket.getOutputStream(); oos = new ObjectOutputStream(out) ; oos.writeObject( student ); socket.shutdownOutput();
InputStream in = socket.getInputStream(); byte[] buf = new byte[100] ; in.read(buf) ; System.out.println("接收到的服务端反馈:" + new String(buf) );
} catch (IOException e) { e.printStackTrace(); } finally{ try { if(oos!=null) oos.close(); if(out!=null) out.close(); if(socket!=null) socket.close(); }catch (IOException e) { e.printStackTrace(); } } } }
|
UDP的实现
DatagramPacket(数据):封装了数据报的数据、数据长度、目标地址和目标端口
DatagramScoket(收发器):接收和发送DatagramPacket中封装好的数据
接收方
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException;
public class Receive {
public static void main(String[] args) { DatagramSocket ds = null ; byte[] data = new byte[64] ; DatagramPacket dp = new DatagramPacket(data , data.length) ; try { ds = new DatagramSocket(9999); ds.receive( dp );
String receiveData = new String(dp.getData(), 0, data.length); System.out.println("接收到的数据:"+receiveData); System.out.println("显示发送方的信息:" + dp.getAddress().getHostAddress() );
} catch (SocketException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { ds.close(); } } }
|
发送方
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| import java.io.IOException; import java.net.*;
public class Send { public static void main(String[] args) { DatagramSocket ds = null ; InetAddress ip = null ; try { ip = InetAddress.getByName("127.0.0.1");
String msg = "helloserver.." ; DatagramPacket dp = new DatagramPacket(msg.getBytes(),msg.length(),ip,9999) ; ds = new DatagramSocket() ; ds.send( dp ); } catch (UnknownHostException e) { e.printStackTrace(); } catch (SocketException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally{ ds.close(); } } }
|
总结:发送数据使用的工具
TCP:字节流
UDP:DatagramScoket
网络编程中一些工具类
InetAddress
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public static void main(String[] args) { InetAddress host = null; try { host = InetAddress.getLocalHost(); System.out.println(host); InetAddress host163 = InetAddress.getByName("www.163.com"); System.out.println(host163); } catch (UnknownHostException e) { e.printStackTrace(); }
}
|
URL/URLConnection
以下示例,注意点:输入流 url-内存; 输出流:内存-本地
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection;
public class URLDemo { public static void main(String[] args) { InputStream in = null ; URLConnection urlConnection = null; OutputStream out = null ; try { URL url = new URL("https://www.163.com/") ; urlConnection = url.openConnection(); in = urlConnection.getInputStream();
out = new FileOutputStream("d:\\163.txt"); byte[] buf = new byte[64] ; int len = -1 ; while( (len = in.read(buf)) != -1 ){ out.write(buf,0,len); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally{ try { if(out!=null) out.close(); if(in!=null) in.close(); } catch (IOException e) { e.printStackTrace(); } } } }
|
参考
https://www.bilibili.com/video/BV114411W7id?p=61
总结
记得学这个是在疫情期间网课学习的,当时用的是C#,VS教学的,到现在都快忘完了,我是喜欢Java!