• 运输层协议----UDP


    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    
    class UDPClient
    {
    	public static void main(String[] args) throws IOException
    	{
    		// 构造数据报套接字并将其绑定到本地主机上任何可用的端口
    		DatagramSocket client = new DatagramSocket();
    		// 在给定主机名的情况下确定主机的 IP 地址
    		InetAddress addr = InetAddress.getByName("127.0.0.1");
    		int port = 10021;
    		for (int i = 0; i < 5; i++)
    		{
    			String sendStr = "Hello! I'm Client" + i;
    			byte[] sendBuf = sendStr.getBytes();
    
    			// 构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。length 参数必须小于等于 buf.length。
    			// buf - 包数据 length - 包长度 address - 目的地址 port - 目的端口号
    			DatagramPacket sendPacket = new DatagramPacket(sendBuf, sendBuf.length, addr, port);
    
    			// 从此套接字发送数据报包。DatagramPacket 包含的信息指示:将要发送的数据、其长度、远程主机的 IP
    			// 地址和远程主机的端口号。
    			client.send(sendPacket);
    
    			byte[] recvBuf = new byte[100];
    
    			// 构造 DatagramPacket,用来接收长度为 length 的数据包。 length 参数必须小于等于
    			// buf.length。
    			DatagramPacket recvPacket = new DatagramPacket(recvBuf, recvBuf.length);
    
    			// 从此套接字接收数据报包。
    			client.receive(recvPacket);
    			String recvStr = new String(recvPacket.getData(), 0, recvPacket.getLength());
    			System.out.println("recvMsg =" + recvStr +"; remotePort =" + recvPacket.getPort());
    		}
    
    		client.close();
    	}
    }
    

      

    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    
    class UDPServer
    {
    	public static void main(String[] args) throws IOException
    	{
    		DatagramSocket server = new DatagramSocket(10021);
    		byte[] recvBuf = new byte[100];
    		for (int i = 0; i < 5; i++)
    		{
    			DatagramPacket recvPacket = new DatagramPacket(recvBuf, recvBuf.length);
    			server.receive(recvPacket);
    			String recvStr = new String(recvPacket.getData(), 0, recvPacket.getLength());
    			int port = recvPacket.getPort();
    			System.out.println("reveMsg = "+ recvStr + "; remote port =" + port);
    
    			InetAddress addr = recvPacket.getAddress();
    			String sendStr = "Hello ! I'm Server" + i;
    
    			byte[] sendBuf = sendStr.getBytes();
    			DatagramPacket sendPacket = new DatagramPacket(sendBuf, sendBuf.length, addr, port);
    
    			server.send(sendPacket);
    		}
    
    		server.close();
    	}
    }
    

    client端输出:

    recvMsg =Hello ! I'm Server0; remotePort =10021
    recvMsg =Hello ! I'm Server1; remotePort =10021
    recvMsg =Hello ! I'm Server2; remotePort =10021
    recvMsg =Hello ! I'm Server3; remotePort =10021
    recvMsg =Hello ! I'm Server4; remotePort =10021

    server端输出:

    reveMsg = Hello! I'm Client0; remote port =61226
    reveMsg = Hello! I'm Client1; remote port =61226
    reveMsg = Hello! I'm Client2; remote port =61226
    reveMsg = Hello! I'm Client3; remote port =61226
    reveMsg = Hello! I'm Client4; remote port =61226

    UDP运输层协议:

    (1)UDP是一种无连接的服务,即在两个进程间没有创建管道时的初始握手阶段。

    (2)因为UDP没有管道,所以当一个进程需要向另一个进程发送一批字节时,该发送进程需要为这批字节附上目的进程地址(IP和port),并且,该过程对于每批由发送进程所发送的字节都必须重复做,见循环中五次发送UDP报文的操作。

           由于UDP当中没有流与套接字相关联,事实上UDP也不是将字节送入与Socket相关的流,而是将一个个分组通过DataGramSocket对象直接发送出去。

    而在TCP运输层协议中:

    (1)TCP在客户机进程和服务机进程之间提供了可靠的字节流服务,一旦建立连接,两端就可以通过与Socket对象相关联的输入输出流来进行数据交互,而不用像UDP那样每次都要通过DataGramSocket对象指明远端IP和port来发送和接收

    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.InetAddress;
    import java.net.InetSocketAddress;
    import java.net.Socket;
    
    class TCPClient
    {
    	public static void main(String[] args) throws IOException
    	{
    		// 构造数据报套接字并将其绑定到本地主机上任何可用的端口
    		Socket client = new Socket();
    		// 在给定主机名的情况下确定主机的 IP 地址
    		InetAddress addr = InetAddress.getByName("127.0.0.1");
    		int port = 10021;
    		client.connect(new InetSocketAddress(addr, port));
    		OutputStream output = client.getOutputStream();
    		InputStream input = client.getInputStream();
    		for (int i = 0; i < 5; i++)
    		{
    			String sendStr = "Hello! I'm Client" + i;
    
    			output.write(sendStr.getBytes());
    
    			byte[] recvBuf = new byte[100];
    
    
    			int length = input.read(recvBuf);
    			String str = new String(recvBuf);
    			System.out.println("recvMsg =" + str.substring(0,length));
    		}
    
    		client.close();
    	}
    }
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    class TCPServer
    {
    	public static void main(String[] args) throws IOException
    	{
    		ServerSocket server = new ServerSocket(10021);
    		Socket socket = server.accept();
    		OutputStream output = socket.getOutputStream();
    		InputStream input = socket.getInputStream();
    		byte[] recvBuf = new byte[100];
    		for (int i = 0; i < 5; i++)
    		{
    			int len = input.read(recvBuf);
    			String str = new String(recvBuf);
    			
    			System.out.println("reveMsg = "+ str.substring(0,len) + "; remote port =" + socket.getRemoteSocketAddress());
    
    			String sendStr = "Hello ! I'm Server" + i;
    
                
    			output.write(sendStr.getBytes());
    		}
    
    		server.close();
    	}
    }
    

    client端输出:

    recvMsg =Hello ! I'm Server0
    recvMsg =Hello ! I'm Server1
    recvMsg =Hello ! I'm Server2
    recvMsg =Hello ! I'm Server3
    recvMsg =Hello ! I'm Server4

    server端输出:

    reveMsg = Hello! I'm Client0; remote port =/127.0.0.1:54233
    reveMsg = Hello! I'm Client1; remote port =/127.0.0.1:54233
    reveMsg = Hello! I'm Client2; remote port =/127.0.0.1:54233
    reveMsg = Hello! I'm Client3; remote port =/127.0.0.1:54233
    reveMsg = Hello! I'm Client4; remote port =/127.0.0.1:54233

      

    这个情景不具有现实意义,当发送数据较大较快的时候,服务端的TCP连接是无法区分数据怎么分离的

    这个设定是buffer足够大,client端发送不够快 如果将buffer设置为2

  • 相关阅读:
    变形与动画
    验证状态、禁用
    选择列表和可多选的选择列表
    浏览——选择文件
    引用
    <abbr> 元素的样式为显示在文本底部的一条虚线边框,当鼠标悬停在上面时会显示完整的文本(只要您为 <abbr> title 属性添加了文本)
    bootstrap强调类名
    bootstrap列排序
    jsp变量的使用规则
    随机生成30个四则运算算式
  • 原文地址:https://www.cnblogs.com/wuxinliulei/p/4855984.html
Copyright © 2020-2023  润新知