诺基亚官方网站,网页设计培训好学吗,wordpress提醒用户注册,网络运维工程师年终总结网络通信协议 java.net 包中提供了两种常见的网络协议的支持:
UDP#xff1a;用户数据报协议(User Datagram Protocol)TCP#xff1a;传输控制协议(Transmission Control Protocol)
TCP协议与UDP协议
TCP协议
TCP协议进行通信的两个应用进程#xff1a;客户端、服务端
…网络通信协议 java.net 包中提供了两种常见的网络协议的支持:
UDP用户数据报协议(User Datagram Protocol)TCP传输控制协议(Transmission Control Protocol)
TCP协议与UDP协议
TCP协议
TCP协议进行通信的两个应用进程客户端、服务端
使用TCP协议前须先建立TCP连接形成基于字节流的传输数据通道传输前采用“三次握手”方式点对点通信是可靠的 TCP协议使用重发机制当一个通信实体发送一个消息给另一个通信实体后需要收到另一个通信实体确认信息如果没有收到另一个通信实体确认信息则会再次重复刚才发送的消息 在连接中可进行大数据量的传输 传输完毕需释放已建立的连接效率低
UDP协议
UDP协议进行通信的两个应用进程发送端、接收端将数据、源、目的封装成数据包(传输的基本单位)不需要建立连接发送不管对方是否准备好接收方收到也不确认不能保证数据的完整性故是不可靠的每个数据报的大小限制在64K内发送数据结束时无需释放资源开销小通信效率高适用场景音频、视频和普通数据的传输。例如视频会议
生活案例 TCP生活案例打电话 UDP生活案例发送短信、发电报 区别
TCP可靠的连接(发送数据前需要三次握手、四次挥手)进行大数据量的传输效率低。UDP不可靠的连接(发送前不需要确认对方是否在)、使用数据报传输(限制在64kb以内)、效率高。
TCP协议
三次握手
TCP协议中在发送数据的准备阶段客户端与服务器之间的三次交互以保证连接的可靠。 完成三次握手连接建立后客户端和服务器就可以开始进行数据传输了。由于这种面向连接的特性TCP协议可以保证传输数据的安全所以应用十分广泛例如下载文件、浏览网页等。
四次挥手
TCP协议中在发送数据结束后释放连接时需要经过四次挥手。
第一次挥手客户端向服务器端提出结束连接让服务器做最后的准备工作。此时客户端处于半关闭状态即表示不再向服务器发送数据了但是还可以接受数据。第二次挥手服务器接收到客户端释放连接的请求后会将最后的数据发给客户端。并告知上层的应用进程不再接收数据。第三次挥手服务器发送完数据后会给客户端发送一个释放连接的报文。那么客户端接收后就知道可以正式释放连接了。第四次挥手客户端接收到服务器最后的释放连接报文后要回复一个彻底断开的报文。这样服务器收到后才会彻底释放连接。这里客户端发送完最后的报文后会等待2MSL因为有可能服务器没有收到最后的报文那么服务器迟迟没收到就会再次给客户端发送释放连接的报文此时客户端在等待时间范围内接收到会重新发送最后的报文并重新计时。如果等待2MSL后没有收到那么彻底断开。
网络编程API
Socket类
基本介绍 示意图: 理解客户端、服务端 客户端 自定义浏览器(browser — server) 服务端 自定义Tomcat服务器
TCP网络编程
通信模型 例题1
客户端发送内容给服务端服务端将内容打印到控制台上。
public class TCPTest1 {//客户端Testpublic void client() {Socket socket null;OutputStream os null;try {// 1.创建一个SocketInetAddress inetAddress InetAddress.getByName(127.0.0.1); //声明ip地址int port 8989; //声明端口号socket new Socket(inetAddress,port);// 2.发送数据os socket.getOutputStream();os.write(你好我是客户端请多多关照.getBytes());} catch (IOException e) {e.printStackTrace();} finally {// 3.关闭socket、流try {if (socket ! null)socket.close();} catch (IOException e) {e.printStackTrace();}try {if (os ! null)os.close();} catch (IOException e) {e.printStackTrace();}}}//服务端Testpublic void server() {ServerSocket serverSocket null;Socket socket null; //阻塞式方法InputStream is null;try {// 1.创建一个ServerSocketint port 8989;serverSocket new ServerSocket(port);// 2.调用accept()接收客户端的Socketsocket serverSocket.accept();System.out.println(服务器端已开启);System.out.println(收到了来自于 socket.getInetAddress().getHostAddress() 的连接);// 3.接收数据is socket.getInputStream();byte[] buffer new byte[1024];ByteArrayOutputStream baos new ByteArrayOutputStream(); //内部维护了一个byte[]int len;while ((len is.read(buffer)) ! -1) {// 错误的可能会出现乱码
// String str new String(buffer,0,len);
// System.out.println(str);//正确的baos.write(buffer,0,len);}System.out.println(baos.toString());System.out.println(\n数据接收完毕);} catch (IOException e) {e.printStackTrace();} finally {// 4.关朗Socket、ServerSocket、流try {if (socket ! null) {socket.close();}} catch (IOException e) {e.printStackTrace();}try {if (serverSocket ! null) {serverSocket.close();}} catch (IOException e) {e.printStackTrace();}try {if (is ! null) {is.close();}} catch (IOException e) {e.printStackTrace();}}}
}例题2
客户端发送文件给服务端服务端将文件保存在本地。
public class TCPTest2 {//客户端Testpublic void client() {// 1.创建Socket// 指明对方即为服务器的ip地址和端口号Socket socket null;FileInputStream fis null;OutputStream os null;try {InetAddress inetAddress InetAddress.getByName(127.0.0.1);int port 9090;socket new Socket(inetAddress,port);// 2.创建File的实例、FileInputstream的实例File file new File(huan.jpg);fis new FileInputStream(file);// 3.通过Socket获取输出流os socket.getOutputStream();// 读写数据byte[] buffer new byte[1024];int len;while ((len fis.read(buffer)) ! -1) {os.write(buffer,0,len);}System.out.println(数据发送完毕);} catch (IOException e) {e.printStackTrace();} finally {// 4.关闭Socket和相关的流try {if (os ! null) {os.close();}} catch (IOException e) {e.printStackTrace();}try {if (fis ! null) {fis.close();}} catch (IOException e) {e.printStackTrace();}try {if (socket ! null) {socket.close();}} catch (IOException e) {e.printStackTrace();}}}//服务端Testpublic void server() {ServerSocket serverSocket null;Socket socket null;InputStream is null;FileOutputStream fos null;try {// 1.创建ServerSocketint port 9090;serverSocket new ServerSocket(port);// 2.接收来自于客户端的socket:accept()socket serverSocket.accept();// 3.通过Socket获取一个输入流is socket.getInputStream();// 4.创建File类的实例、File0utputstream的实例File file new File(huan_copy.jpg);fos new FileOutputStream(file);// 5.读写过程byte[] buffer new byte[1024];int len;while ((len is.read(buffer)) ! -1) {fos.write(buffer,0,len);}System.out.println(数据接收完毕);} catch (IOException e) {e.printStackTrace();} finally {// 6.关闭相关的Socket和流try {if (fos ! null) {fos.close();}} catch (IOException e) {e.printStackTrace();}try {if (is ! null) {is.close();}} catch (IOException e) {e.printStackTrace();}try {if (socket ! null) {socket.close();}} catch (IOException e) {e.printStackTrace();}try {if (serverSocket ! null) {serverSocket.close();}} catch (IOException e) {e.printStackTrace();}try {if (is ! null) {is.close();}} catch (IOException e) {e.printStackTrace();}}}
}例题3
从客户端发送文件给服务端服务端保存到本地。并返回“发送成功给客户端。并关闭相应的连接。
public class TCPTest3 {//客户端Testpublic void client() {// 1.创建Socket// 指明对方即为服务器的ip地址和端口号Socket socket null;FileInputStream fis null;OutputStream os null;ByteArrayOutputStream baos null;InputStream is null;try {InetAddress inetAddress InetAddress.getByName(127.0.0.1);int port 9090;socket new Socket(inetAddress, port);// 2.创建File的实例、FileInputstream的实例File file new File(huan.jpg);fis new FileInputStream(file);// 3.通过Socket获取输出流os socket.getOutputStream();// 4.读写数据byte[] buffer new byte[1024];int len;while ((len fis.read(buffer)) ! -1) {os.write(buffer, 0, len);}System.out.println(数据发送完毕);// 5.客户端表明不再继续发送数据socket.shutdownOutput();// 6.接收来自于服务器端的数据is socket.getInputStream();baos new ByteArrayOutputStream();byte[] buffer1 new byte[5];int len1;while ((len1 is.read(buffer1)) ! -1) {baos.write(buffer1, 0, len1);}System.out.println(baos.toString());} catch (IOException e) {e.printStackTrace();} finally {// 7.关闭Socket和相关的流try {baos.close();} catch (Exception e) {e.printStackTrace();}try {is.close();} catch (IOException e) {e.printStackTrace();}try {if (os ! null) {os.close();}} catch (IOException e) {e.printStackTrace();}try {if (fis ! null) {fis.close();}} catch (IOException e) {e.printStackTrace();}try {if (socket ! null) {socket.close();}} catch (IOException e) {e.printStackTrace();}}}//服务端Testpublic void server() {ServerSocket serverSocket null;Socket socket null;InputStream is null;FileOutputStream fos null;OutputStream os null;try {// 1.创建ServerSocketint port 9090;serverSocket new ServerSocket(port);// 2.接收来自于客户端的socket:accept()socket serverSocket.accept();// 3.通过Socket获取一个输入流is socket.getInputStream();// 4.创建File类的实例、File0utputstream的实例File file new File(huan_copy2.jpg);fos new FileOutputStream(file);// 5.读写过程byte[] buffer new byte[1024];int len;while ((len is.read(buffer)) ! -1) {fos.write(buffer, 0, len);}// 6.服务端发送数据给客户端os socket.getOutputStream();os.write(你的图片很漂亮我接收到了.getBytes());System.out.println(数据接收完毕);} catch (IOException e) {e.printStackTrace();} finally {// 7.关闭相关的Socket和流try {os.close();} catch (IOException e) {e.printStackTrace();}try {if (fos ! null) {fos.close();}} catch (IOException e) {e.printStackTrace();}try {if (is ! null) {is.close();}} catch (IOException e) {e.printStackTrace();}try {if (socket ! null) {socket.close();}} catch (IOException e) {e.printStackTrace();}try {if (serverSocket ! null) {serverSocket.close();}} catch (IOException e) {e.printStackTrace();}try {if (is ! null) {is.close();}} catch (IOException e) {e.printStackTrace();}}}
}【案例】聊天室
聊天室模型 服务器端
public class ChatSeverTest {//这个集合用来存储所有在线的客户端static ArrayListSocket online new ArrayListSocket();public static void main(String[] args) throws IOException {//1、启动服务器绑定端口号ServerSocket server new ServerSocket(8989);//2、接收n多的客户端同时连接while (true) {Socket accept server.accept();online.add(accept);//把新连接的客户端添加到online列表中MessageHandler mh new MessageHandler(accept);mh.start();}}static class MessageHandler extends Thread {private Socket socket;private String ip;public MessageHandler(Socket socket) {super();this.socket socket;}Overridepublic void run() {try {ip socket.getInetAddress().getHostAddress();//插入给其他客户端转发“我上线了”sendToOther(ip上线了);//(1)接收该客户端的发送的消息InputStream input socket.getInputStream();InputStreamReader reader new InputStreamReader(input);BufferedReader br new BufferedReader(reader);String str;while ((str br.readLine()) ! null) {//(2)给其他在线客户端转发sendToOther(ip : str);}sendToOther(ip 下线了);} catch (IOException e) {try {sendToOther(ip 掉线了);} catch (Exception e1) {e1.printStackTrace();}} finally {//从在线人员中移除我online.remove(socket);}}//封装一个方法给其他客户端转发xxx消息public void sendToOther(String message) throws IOException {//遍历所有的在线客户端一一转发for (Socket on : online) {OutputStream every on.getOutputStream();PrintStream ps new PrintStream(every);ps.println(message);}}}
}客户端
public class ChatClientTest {public static void main(String[] args) throws Exception {//1、连接服务器Socket socket new Socket(127.0.0.1, 8989);//2、开启两个线程//(1)一个线程负责看别人聊即接收服务器转发的消息Receive receive new Receive(socket);receive.start();//(2)一个线程负责发送自己的话Send send new Send(socket);send.start();send.join();//等我发送线程结束了才结束整个程序socket.close();}
}class Send extends Thread{private Socket socket;public Send(Socket socket) {super();this.socket socket;}Overridepublic void run() {try {OutputStream outputStream socket.getOutputStream();//按行打印PrintStream ps new PrintStream(outputStream);Scanner input new Scanner(System.in);//从键盘不断的输入自己的话给服务器发送由服务器给其他人转发while (true) {System.out.println(自己的话);String str input.nextLine();if (bye.equals(str)) {break;}ps.println(str);}input.close();} catch (IOException e) {e.printStackTrace();}}
}class Receive extends Thread{private Socket socket;public Receive(Socket socket) {super();this.socket socket;}Overridepublic void run() {try {InputStream inputStream socket.getInputStream();Scanner input new Scanner(inputStream);while (input.hasNextLine()) {String line input.nextLine();System.out.println(line);}} catch (IOException e) {e.printStackTrace();}}
}UDP网络编程
通信模型 示例
public class UDPTest {//发送端Testpublic void sender() throws Exception {//1.创建DatagramSocket的实例DatagramSocket ds new DatagramSocket();//2、将数据、目的地的ip目的地的端口号部封装在DatagramPacket数据报中InetAddress inetAddress InetAddress.getByName(127.0.0.1);int port 9090;byte[] bytes 我是发送端.getBytes(utf-8);DatagramPacket packet new DatagramPacket(bytes, 0, bytes.length, inetAddress, port);//发送数据ds.send(packet);ds.close();}//接收端Testpublic void receiver() throws IOException {//1.创建DatagramSocket的实例int port 9090;DatagramSocket ds new DatagramSocket(port);//2. 创建数据报的对象用于接收发送端发送过来的数据byte[] buffer new byte[1024 * 64];DatagramPacket packet new DatagramPacket(buffer, 0, buffer.length);//3.接收数据ds.receive(packet);//4.获取数据并打印到控制台上String str new String(packet.getData(), 0, packet.getLength());System.out.println(str);ds.close();}
}