TCP 网络通信
TCP:可靠的传输层协议
服务端:
package com.zhiwei.net;import java.io.DataInputStream;import java.io.IOException;import java.io.InputStream;import java.net.ServerSocket;import java.net.Socket;/*** * 简单的TCP服务端类 * ①:创建ServerSocket:数据码头 * ②:创建Socket:数据码头集装箱:真正的数据集中站 * ③:解析Socket获取InputStream和OutputStream对象 * InputStream和OutputStream都和同一个Socket关联, * InputStream:负责接受客户端的数据 * OutputStream:负责对客户端做出响应 *注:Tomcat的Http请求也是利用该原理,连接器接受客户端请求负责创建HttpRequest和HttpResponse对象(本质解析Socket),然后调用处理器处理 * @author Yang Zhiwei * */public class SimpleTCPServer { private static boolean flag=true; //服务器开启标志 public static void main(String[] args) throws Exception { ServerSocket serverSocket=new ServerSocket(8888); while(flag){ //当服务端程序运行到该阶段时线程阻塞,直到接受客户端请求才向下流转(Debug可以查看) Socket socket=serverSocket.accept(); new ServerService(socket).run(); } serverSocket.close(); } }class ServerService implements Runnable{ private Socket socket=null; public ServerService(Socket socket) { this.socket=socket; } @Override public void run() { InputStream is = null; DataInputStream dis = null; try { is = socket.getInputStream(); dis=new DataInputStream(is); System.out.println("客户端请求内容:"+dis.readUTF()); } catch (Exception e) { e.printStackTrace(); }finally{ try { if(dis!=null){ dis.close(); } socket.close(); } catch (IOException e) { e.printStackTrace(); } } }}
客户端:
package com.zhiwei.net;import java.io.DataOutputStream;import java.io.OutputStream;import java.net.Socket;/** * TCP客户端的创建 * ①:创建Socket:数据集装箱:必须指定服务端的地址 * ②:解析Socket数据:负责和服务端的具体数据通信 * @author Yang Zhiwei * */public class SimpleTCPClient { public static void main(String[] args) throws Exception { Socket socket=new Socket("127.0.0.1", 8888); OutputStream os=socket.getOutputStream(); DataOutputStream dos=new DataOutputStream(os); dos.writeUTF("Hello Server....."); dos.close(); socket.close(); }}
结果:
UDP 网络通信
UDP是无状态的传输层协议,如果对数据的要求不高完全可以使用UDP协议,减少资源的浪费,UDP不保证数据的可靠性,常见的QQ通讯工具是使用UDP协议的,只是在应用层的基础上保证QQ消息的不丢失,并不是采用TCP的传输协议
服务端:
package com.zhiwei.net;import java.net.DatagramPacket;import java.net.DatagramSocket;//服务器端接受客户端数据public class UDPServer { public static void main(String[] args) throws Exception{ //创建数据接收码头,只接受和客户端约定的3000端口的数据 DatagramSocket ds=new DatagramSocket(3000); //创建数据接收的数据缓冲区 byte[] buf=new byte[1024]; DatagramPacket dp=new DatagramPacket(buf,1024); //接受来自端口1024的数据包,并存储在集装箱datagramPacket中:注意一旦服务器开启,就会自动监听3000端口,如果 没有数据,则进行阻塞 ds.receive(dp); //解析数据包中的信息 String data=new String(dp.getData(),0,dp.getLength()); String ip=dp.getAddress().getHostAddress(); int port=dp.getPort(); System.out.println("ip地址:"+ip+" 端口号:"+port+" 消息:"+data); ds.close(); }}
客户端:
package com.zhiwei.net;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;//发送数据给服务器:注意若服务器端未开启就发送数据,数据包很可能会丢失public class UDPClient { public static void main(String[] args) throws Exception { //数据包套接字:相当于码头,专门处理通信数据及进行数据转发设置的 DatagramSocket ds=new DatagramSocket(); String message="Hello Java World!"; //数据报包:类似于集装箱,用来存储所有的数据信息 DatagramPacket dp=new DatagramPacket( message.getBytes(), //数据都是已字节数据进行发送的,因此需要将数据进行转换 message.length(), //发送数据的长度 InetAddress.getByName("127.0.0.1"), //发送数据的源ip地址 3000 //发送数据的端口号 ); ds.send(dp); //数据包通过码头DatagramSocket发送出去 ds.close(); //数据发送之后关闭通道,减少资源浪费 }}
结果: