首页 > 其他 > 详细

TCP和UDP学习总结

时间:2020-05-31 12:26:56      阅读:36      评论:0      收藏:0      [点我收藏+]

总结

TCP

TCP:客户端和服务端连接用socket套接字,传输数据时,用输出流输出(OutputStream)。


传输字符串

客户端

public class TcpClientDemo1 {
   public static void main(String[] args) {
       OutputStream outputStream = null;
       try {
           //1、要知道服务端的地址
           InetAddress inetAddress = InetAddress.getByName("127.0.0.1");
           int port = 9999;
           //创建一个socket连接
           Socket socket = new Socket(inetAddress,port);
           //发送消息
           outputStream = socket.getOutputStream();
           outputStream.write("欢迎学习".getBytes());
           outputStream.flush();
?
      } catch (Exception e) {
           e.printStackTrace();
      }finally {
           if (outputStream != null) {
               try {
                   outputStream.close();
              } catch (IOException e) {
                   e.printStackTrace();
              }
          }
      }
?
?
?
  }
}

服务端

public class TcpServerDemo1 {
   public static void main(String[] args) {
       //1、服务端需要一个地址
       ServerSocket serverSocket = null;
       InputStream inputStream = null;
       Socket socket = null;
       ByteArrayOutputStream byteArrayOutputStream = null;
?
       try {
           serverSocket = new ServerSocket(9999);
           //接收
           socket = serverSocket.accept();
           //读取客户端的消息
           inputStream = socket.getInputStream();
?
//           byte[] bytes = new byte[1024];
//           int len;
//           while ((len = inputStream.read(bytes)) != -1){
//               System.out.println(new String(bytes,0,len));
//           }
           //管道流
           byteArrayOutputStream = new ByteArrayOutputStream();
           byte[] bytes = new byte[1024];
           int len;
           while ((len=inputStream.read(bytes))!= -1){
               byteArrayOutputStream.write(bytes,0,len);
          }
           System.out.println(byteArrayOutputStream.toString());
?
      } catch (IOException e) {
           e.printStackTrace();
      }finally {
           if (byteArrayOutputStream != null) {
               try {
                   byteArrayOutputStream.close();
              } catch (IOException e) {
                   e.printStackTrace();
              }
          }
           if (inputStream != null) {
               try {
                   inputStream.close();
              } catch (IOException e) {
                   e.printStackTrace();
              }
          }
           if (socket != null) {
               try {
                   socket.close();
              } catch (IOException e) {
                   e.printStackTrace();
              }
?
          }
           if (serverSocket != null) {
               try {
                   serverSocket.close();
              } catch (IOException e) {
                   e.printStackTrace();
              }
          }
?
      }
  }
}

传输文件

客户端

public class TcpClientDemo02 {
   public static void main(String[] args) throws Exception {
       //上传文件,用Socket连接
       //Socket连接需要传服务端的IP和端口
       Socket socket = new Socket(InetAddress.getByName("localhost"),8888);
//       DatagramSocket socket = new DatagramSocket(8888); //自己端口号位8888
?
       //将数据打包成一个包裹
       byte[] bytes = new byte[1024];
       //上传一个文件,将文件读出来
       FileInputStream fis = new FileInputStream("网络编程/meitu.jpg");//使用相对路径
       //IO流的老一套
       int len;
       //上传文件,不需要打包,直接用输出流
       OutputStream os = socket.getOutputStream();
       while ((len=fis.read(bytes)) != -1){
           os.write(bytes,0,len);
      }
       os.flush();
//
//       DatagramPacket packet = new DatagramPacket(bytes,0,bytes.length);//包裹要求数据必须为byte数组形式,需要服务端的IP还有端口号
//
//       //将数据传送给服务端
//       socket.send();
?
       fis.close();
       os.close();
       socket.close();
  }
}

服务端

public class TcpServerDemo02 {
   public static void main(String[] args) throws Exception {
       //创建一个端口为8888的socket连接的服务端
       ServerSocket serverSocket = new ServerSocket(8888);
?
       //监听连接
       Socket socket = serverSocket.accept();
?
       //创建输入流,接收客户端输出流的数据
       InputStream is = socket.getInputStream();
       //使用管道流来将读出的数据加载到服务端硬盘中
       FileOutputStream fos = new FileOutputStream(new File("receive.jpg"));
       //IO流一套
       byte[] bytes = new byte[1024];
       int len;
       while ((len=is.read(bytes))!=-1){
           fos.write(bytes,0,len);
      }
?
       fos.close();
       is.close();
       socket.close();
       serverSocket.close();
?
  }
}

小结

1、使用TCP模式,不管是客户端还是服务端,在写数据时都用管道流进行输出。

问题:如何让服务端给客户端发送信息?

 

UDP

多线程实现聊天咨询

聊天对话的传输端

public class TalkClient implements Runnable {
   DatagramSocket socket = null;
   BufferedReader reader = null;
?
   private String toIP;
   private int fromPort;
   private int toPort;
?
   public TalkClient( int fromPort, int toPort,String toIP) {
       this.toIP = toIP;
       this.fromPort = fromPort;
       this.toPort = toPort;
       try {
           socket = new DatagramSocket(this.fromPort);
           reader = new BufferedReader(new InputStreamReader(System.in));
      } catch (SocketException e) {
           e.printStackTrace();
      }
?
  }
?
   @Override
   public void run() {
       while (true) {
?
           try {
               String data = reader.readLine();
               byte[] bytes = data.getBytes();
?
               DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length, new InetSocketAddress(this.toIP,this.toPort));
               //3、发送包
               socket.send(packet);
?
               if (data.equals("bye")) {
                   break;
              }
          } catch (Exception e) {
               e.printStackTrace();
          }
           socket.close();
      }
  }
}

接收端

public class TalkReceive implements Runnable{
   DatagramSocket socket = null;
?
   private int port;
   private String msgFrom;
?
   public TalkReceive(int port,String msgFrom) {
       this.port = port;
       this.msgFrom = msgFrom;
?
       try {
           socket = new DatagramSocket(port);
      } catch (SocketException e) {
           e.printStackTrace();
      }
  }
?
   @Override
   public void run() {
       while (true){
           try {
               byte[] container = new byte[1024];
               DatagramPacket packet = new DatagramPacket(container,0,container.length);
               socket.receive(packet);
?
               byte[] data = packet.getData();
               String s = new String(data,0,packet.getLength());
?
               System.out.println(this.msgFrom+":"+s);
?
               if (s.equals("bye")){
                   break;
              }
          } catch (Exception e) {
               e.printStackTrace();
          }
      }
       socket.close();
?
  }
}

学生

public class TalkStudent {
   public static void main(String[] args) {
       //开启两个线程
       new Thread(new TalkClient(7777,9999,"localhost")).start();
       new Thread(new TalkReceive(8888,"老师")).start();
  }
?
}

老师

public class TalkTeacher {
   public static void main(String[] args) {
       //开启两个线程
       new Thread(new TalkClient(6666,8888,"localhost")).start();
       new Thread(new TalkReceive(9999,"学生")).start();
  }
}

小结

学生和老师,都同时拥有接收端和发送端,所以要分别为其分配不同的端口号。

TCP和UDP学习总结

原文:https://www.cnblogs.com/lee-leo/p/12996727.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!