Java开发之路

文章32 |   阅读 14698 |   点赞0

来源:https://blog.csdn.net/sunnyyoona

[Java]UDP通信的简单例子

x33g5p2x  于2021-03-13 发布在 其他  
字(7.0k)|赞(0)|评价(0)|浏览(404)
  1. package com.sjf;
  2. import java.io.IOException;
  3. import java.net.DatagramPacket;
  4. import java.net.DatagramSocket;
  5. import java.net.InetAddress;
  6. import java.net.InetSocketAddress;
  7. import java.net.SocketException;
  8. /**
  9. * @time 2015-05-27
  10. * @desc UDP通信
  11. * @author sjf0115
  12. *
  13. */
  14. public class Server {
  15. private byte[] buffer = new byte[1024];
  16. private DatagramSocket socket = null;
  17. private DatagramPacket packet = null;
  18. private InetSocketAddress socketAddress = null;
  19. private InetAddress clientAddress;
  20. private String clientIP;
  21. private int clientPort;
  22. private String clientData;
  23. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  24. /**
  25. * 构造函数,绑定主机和端口.
  26. * @param ip IP 地址
  27. * @param port 端口
  28. * @throws Exception
  29. */
  30. public Server(String ip, int port) throws Exception
  31. {
  32. // 绑定IP地址和端口.
  33. Bind(ip,port);
  34. System.out.println("[服务端启动]");
  35. }
  36. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  37. public Server() throws SocketException
  38. {
  39. // 构造数据报套接字并将其绑定到本地主机上任何可用的端口
  40. socket = new DatagramSocket();
  41. System.out.println("[服务端启动]");
  42. }
  43. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  44. /**
  45. * 绑定监听地址和端口.
  46. * @param ip IP地址
  47. * @param port 端口
  48. * @throws SocketException
  49. */
  50. public void Bind(String ip, int port) throws SocketException {
  51. // 根据 IP 地址和端口号创建套接字地址
  52. socketAddress = new InetSocketAddress(ip, port);
  53. // 创建数据报套接字,将其绑定到指定的本地地址
  54. socket = new DatagramSocket(socketAddress);
  55. packet = new DatagramPacket(buffer, buffer.length);
  56. }
  57. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  58. public final String getOrgIp()
  59. {
  60. return clientIP;
  61. }
  62. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  63. /**
  64. * 设置超时时间
  65. * @param timeout 超时时间
  66. * @throws Exception
  67. */
  68. public void SetTimeout(int timeout) throws Exception
  69. {
  70. /* 启用/禁用带有指定超时值的 SO_TIMEOUT,以毫秒为单位。
  71. * 将此选项设为非零的超时值时,对此 DatagramSocket 调用 receive() 将只阻塞此时间长度。
  72. * 如果超过超时值,将引发 java.net.SocketTimeoutException,虽然 DatagramSocket 仍旧有效。
  73. * 选项必须在进入阻塞操作前被启用才能生效。
  74. */
  75. socket.setSoTimeout(timeout);
  76. }
  77. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  78. /**
  79. * 获得超时时间.
  80. * @return 返回超时时间.
  81. * @throws Exception
  82. */
  83. public int GetTimeout() throws Exception
  84. {
  85. return socket.getSoTimeout();
  86. }
  87. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  88. /**
  89. * 接收数据包,该方法会造成线程阻塞.
  90. * @return 返回接收的数据串信息
  91. * @throws IOException
  92. */
  93. public String Receive() throws IOException
  94. {
  95. /*
  96. * 从此套接字接收数据报包。当此方法返回时,DatagramPacket 的缓冲区填充了接收的数据。
  97. * 数据报包也包含发送方的 IP 地址和发送方机器上的端口号。此方法在接收到数据报前一直阻塞。
  98. * 数据报包对象的 length 字段包含所接收信息的长度。如果信息比包的长度长,该信息将被截短。
  99. */
  100. socket.receive(packet);
  101. // 数据报包包含发送方的 IP 地址
  102. clientAddress = packet.getAddress();
  103. clientIP = clientAddress.getHostAddress();
  104. // 数据报包包含发送方的端口号
  105. clientPort = packet.getPort();
  106. // 数据报包包含发送方的数据
  107. clientData = new String(packet.getData(), 0, packet.getLength());
  108. return " ["+clientData+"]";
  109. }
  110. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  111. /**
  112. * 将响应包发送给请求端.
  113. * @param bytes 回应报文
  114. * @throws IOException
  115. */
  116. public void Send(String info) throws IOException
  117. {
  118. packet.setAddress(clientAddress);
  119. packet.setPort(clientPort);
  120. packet.setData(info.getBytes());
  121. /*
  122. * 从此套接字发送数据报包。DatagramPacket 包含的信息指示:将要发送的数据、其长度、远程主机的 IP 地址和远程主机的端口号。
  123. */
  124. socket.send(packet);
  125. }
  126. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  127. /**
  128. * 关闭udp监听口.
  129. */
  130. public void close()
  131. {
  132. try
  133. {
  134. socket.close();
  135. }
  136. catch (Exception ex)
  137. {
  138. ex.printStackTrace();
  139. }
  140. }
  141. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  142. /**
  143. * 测试方法.
  144. * @param args
  145. * @throws Exception
  146. */
  147. public static void main(String[] args) throws Exception {
  148. String serverHost = "127.0.0.1";
  149. int serverPort = 3344;
  150. Server udpServerSocket = new Server(serverHost, serverPort);
  151. while (true)
  152. {
  153. String info = udpServerSocket.Receive();
  154. System.out.println("["+udpServerSocket.clientPort+"]->"+info);
  155. udpServerSocket.Send("Reponse-----"+info);
  156. }
  157. }
  158. }
  1. package com.sjf;
  2. import java.io.*;
  3. import java.net.*;
  4. /**
  5. * @time 2015-05-27
  6. * @desc UDP通信
  7. * @author QPING
  8. */
  9. public class Client {
  10. private byte[] buffer = new byte[1024];
  11. private DatagramSocket socket = null;
  12. private InetSocketAddress socketAddress = null;
  13. private String clientIP;
  14. private int clientPort;
  15. private String clientData;
  16. private InetAddress clientAddress;
  17. private DatagramPacket sendPacket;
  18. private DatagramPacket receivePacket;
  19. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  20. public Client(String host, int port) throws Exception
  21. {
  22. // 根据 IP 地址和端口号创建套接字地址
  23. socketAddress = new InetSocketAddress(host, port);
  24. // 创建数据报套接字,将其绑定到指定的本地地址
  25. socket = new DatagramSocket(socketAddress);
  26. System.out.println("服务端启动!");
  27. }
  28. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  29. /**
  30. * 构造函数,创建UDP客户端
  31. * @throws Exception
  32. */
  33. public Client() throws Exception
  34. {
  35. socket = new DatagramSocket();
  36. }
  37. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  38. /**
  39. * 设置超时时间,该方法必须在bind方法之后使用.
  40. * @param timeout 超时时间
  41. * @throws Exception
  42. */
  43. public final void SetTimeout(final int timeout) throws Exception
  44. {
  45. socket.setSoTimeout(timeout);
  46. }
  47. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  48. /**
  49. * 获得超时时间.
  50. * @return 返回超时时间
  51. * @throws Exception
  52. */
  53. public int GetTimeout() throws Exception
  54. {
  55. return socket.getSoTimeout();
  56. }
  57. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  58. public DatagramSocket GetSocket()
  59. {
  60. return socket;
  61. }
  62. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  63. /**
  64. * 向指定的服务端发送数据信息.
  65. * @param ip 服务器主机地址
  66. * @param port 服务端端口
  67. * @param bytes 发送的数据信息
  68. * @return 返回构造后俄数据报
  69. * @throws IOException
  70. */
  71. public DatagramPacket Send(String ip,int port,String info) throws IOException
  72. {
  73. byte[] bytes = info.getBytes();
  74. sendPacket = new DatagramPacket(bytes, bytes.length);
  75. sendPacket.setAddress(InetAddress.getByName(ip));
  76. sendPacket.setPort(port);
  77. socket.send(sendPacket);
  78. return sendPacket;
  79. }
  80. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  81. /**
  82. * 接收从指定的服务端发回的数据.
  83. * @param lhost 服务端主机
  84. * @param lport 服务端端口
  85. * @return 返回从指定的服务端发回的数据.
  86. * @throws Exception
  87. */
  88. public String Receive(String lhost,int lport) throws Exception
  89. {
  90. receivePacket = new DatagramPacket(buffer, buffer.length);
  91. socket.receive(receivePacket);
  92. // 数据报包包含发送方的 IP 地址
  93. clientAddress = receivePacket.getAddress();
  94. clientIP = clientAddress.getHostAddress();
  95. // 数据报包包含发送方的端口号
  96. clientPort = receivePacket.getPort();
  97. // 数据报包包含发送方的数据
  98. clientData = new String(receivePacket.getData(), 0, receivePacket.getLength());
  99. return "["+clientData+"]";
  100. }
  101. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  102. /**
  103. * 关闭udp连接.
  104. */
  105. public void close()
  106. {
  107. try
  108. {
  109. socket.close();
  110. }
  111. catch (Exception ex)
  112. {
  113. ex.printStackTrace();
  114. }
  115. }
  116. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  117. /**
  118. * 测试客户端发包和接收回应信息的方法.
  119. * @param args
  120. * @throws Exception
  121. */
  122. public static void main(String[] args) throws Exception {
  123. String serverHost = "127.0.0.1";
  124. int serverPort = 3344;
  125. String myIP = "127.0.0.2";
  126. int myPort = 3333;
  127. Client client = new Client(myIP,myPort);
  128. while(true)
  129. {
  130. BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  131. System.out.println("["+myPort+"] ");
  132. String str = br.readLine();
  133. client.Send(serverHost, serverPort, str);
  134. String info = client.Receive(serverHost, serverPort);
  135. System.out.println("["+client.clientPort+"]->" + info);
  136. }
  137. }
  138. }

相关文章