来自/原文 : http://blog.chinaunix.net/uid-540802-id-446145.html
以下是服务器端代码,代码在接收到请求后,处理交给线程池。线程池在处理完成后回复报文线客户端。
里面加入了一些性能统计功能,加入了处理报文数量的计数器,还有一个线程统计每秒收到的报文数。
- package com.chouy.udpdns;
- import java.io.IOException;
- import java.net.DatagramPacket;
- import java.net.DatagramSocket;
- import java.net.InetSocketAddress;
- import java.net.SocketAddress;
- import java.net.SocketException;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import java.util.concurrent.atomic.AtomicInteger;
- public class UDPServer
- {
- String host;
- int port;
- ExecutorService executor;
- DatagramSocket datagramSocket;
- AtomicInteger receiveCount;
- public UDPServer(String host, int port)
- {
- this.host = host;
- this.port = port;
- }
- public void setExecutor(ExecutorService executor)
- {
- this.executor = executor;
- }
- public void start() throws SocketException
- {
- this.receiveCount = new AtomicInteger(0);
- Thread t = new TimeThread(this.receiveCount, 1000);
- t.setPriority(Thread.MAX_PRIORITY);
- t.start();
- SocketAddress socketAddress = new InetSocketAddress(host, port);
- this.datagramSocket = new DatagramSocket(socketAddress);
- this.datagramSocket.setReceiveBufferSize(1024 * 1000);
- System.out.println("UDPServer start ... " + socketAddress);
- while (true)
- {
- try
- {
- DatagramPacket packet = DatagramSocketFactory.getDatagramPacket();
- this.datagramSocket.receive(packet);
- this.receiveCount.incrementAndGet();
- if (this.executor != null)
- this.executor.execute(new UDPRunnable(packet));
- else
- {
- DatagramPacket p = new DatagramPacket(packet.getData(), packet.getLength());
- // System.out.println("from ip:port " +this.packet.getAddress() + ":" + this.packet.getPort());
- p.setSocketAddress(packet.getSocketAddress());
- datagramSocket.send(p);
- }
- }
- catch (IOException e)
- {
- e.printStackTrace();
- }
- }
- }
- class UDPRunnable implements Runnable
- {
- DatagramPacket packet;
- public UDPRunnable(DatagramPacket packet)
- {
- this.packet = packet;
- }
- @Override
- public void run()
- {
- try
- {
- DatagramPacket p = new DatagramPacket(this.packet.getData(), this.packet.getLength());
- // System.out.println("from ip:port " +this.packet.getAddress() + ":" + this.packet.getPort());
- p.setSocketAddress(this.packet.getSocketAddress());
- datagramSocket.send(p);
- }
- catch (IOException e)
- {
- e.printStackTrace();
- }
- }
- }
- class TimeThread extends Thread
- {
- long period;
- AtomicInteger atom;
- private int temp;
- public TimeThread(AtomicInteger atomInt, int period)
- {
- this.atom = atomInt;
- this.period = period;
- this.temp = 0;
- }
- @Override
- public void run()
- {
- while (true)
- {
- int t = this.atom.get();
- if (t != this.temp)
- {
- System.out.printf("second recv: %6d, recv sum: %8d\n", (t - this.temp), t);
- this.temp = t;
- }
- try
- {
- Thread.sleep(this.period);
- }
- catch (InterruptedException e)
- {
- e.printStackTrace();
- }
- }
- }
- }
- public static void main(String[] args) throws IOException
- {
- UDPServer udpServer = new UDPServer("0.0.0.0", 1800);
- udpServer.setExecutor(Executors.newFixedThreadPool(1));
- udpServer.start();
- }
- }
下面是客户端代码,也加入了计数器和线程池功能,但在测试中发现线程个数对性能提升不明显。
- package com.chouy.udpdns;
- import java.io.IOException;
- import java.net.DatagramPacket;
- import java.net.DatagramSocket;
- import java.net.InetSocketAddress;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import java.util.concurrent.atomic.AtomicInteger;
- public class UDPClient
- {
- public static AtomicInteger atomicInteger;
- public String host;
- public int port;
- public ExecutorService executorService;
- public DatagramSocket datagramSocket;
- public UDPClient(String host, int port)
- {
- this.host = host;
- this.port = port;
- }
- public void setExecutor(ExecutorService executorService)
- {
- this.executorService = executorService;
- }
- public void start(int nums)
- {
- Runtime.getRuntime().addShutdownHook(new Thread()
- {
- @Override
- public void run()
- {
- System.out.println("exit, count: " + atomicInteger.get());
- }
- });
- try
- {
- datagramSocket = new DatagramSocket();
- datagramSocket.connect(new InetSocketAddress(host, port));
- byte[] bs = "你好".getBytes();
- DatagramPacket packet = new DatagramPacket(bs, bs.length);
- // packet.setAddress(socketAddress);
- // datagramSocket.connect(socketAddress);
- datagramSocket.setSoTimeout(30000);
- atomicInteger = new AtomicInteger(nums);
- for (int i = 0; i < nums; i++)
- {
- // System.out.println("send success");
- this.executorService.execute(new UDPClientRunnable(packet));
- }
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
- while (!this.executorService.isTerminated())
- if (atomicInteger.get() >= 1)
- Thread.currentThread().yield();
- else
- {
- break;
- }
- System.out.println(" main thread ended ... ");
- System.exit(0);
- }
- class UDPClientRunnable implements Runnable
- {
- DatagramPacket packet;
- public UDPClientRunnable(DatagramPacket p)
- {
- this.packet = p;
- }
- @Override
- public void run()
- {
- try
- {
- datagramSocket.send(packet);
- DatagramPacket p2 = new DatagramPacket(new byte[100], 100);
- datagramSocket.receive(p2);
- System.out.println(new String(p2.getData(), 0, p2.getLength()) + " "
- + atomicInteger.decrementAndGet());
- }
- catch (IOException e)
- {
- System.out.println(e.getMessage());
- atomicInteger.decrementAndGet();
- }
- }
- }
- public static void main(String[] args)
- {
- UDPClient client = new UDPClient("192.168.21.117", 1800);
- client.setExecutor(Executors.newFixedThreadPool(100));
- client.start(100000);
- }
- }
下面是一个工厂类,只是在服务器端生成接收报文用,实际没啥大用。
- package com.chouy.udpdns;
- import java.net.DatagramPacket;
- public class DatagramSocketFactory
- {
- final static int bufferSize = 2048;
- public static DatagramPacket getDatagramPacket()
- {
- byte[] buffer = new byte[bufferSize];
- DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
- return packet;
- }
- }
因为代码非常简单,所以没有注释。
相关推荐
在这个主题中,我们将深入理解如何在Java中实现UDP服务器和客户端。 首先,`UDPServer.java` 文件应该包含了服务器端的代码。在Java中,我们使用`java.net.DatagramSocket` 类来创建一个UDP套接字,用于接收和发送...
3. 创建UDP服务器端: - 实例化DatagramSocket并绑定到特定端口。 - 创建一个DatagramPacket,准备接收数据。 - 使用receive()方法接收数据包。 4. 创建UDP客户端: - 实例化DatagramSocket。 - 创建一个...
本资源包含基于JAVA实现的TCP和UDP服务器及客户端程序,非常适合用于学习和课程设计。下面将详细介绍TCP与UDP的特点、工作原理以及它们在JAVA中的应用。 TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议...
在标题和描述中提到的"UDP服务器和客户端程序",这是指使用UDP协议进行通信的两个程序实例,一个作为服务端接收数据,另一个作为客户端发送数据。通常,开发这样的程序需要理解以下几个关键概念: 1. **端口号**:...
【Socket编程】--UDP异步通讯一服务器多客户端 Socket编程是网络通信的基础,而UDP(User Datagram Protocol)是一种无连接、不可靠的传输协议,适用于实时性要求高但对数据完整性要求相对较低的场景。在这个项目中...
Java实现UDP服务器模型,内含UDP服务器端模型和UDP客户端模型两个小程序,向JAVA初学者演示UDP C/S结构的原理。比如客户端模型如下: DatagramSocket socket=new DatagramSocket(); //实例化一个数据报Socket ...
在这个Java实现的UDP简易客户端与服务器端程序中,我们可以通过两个核心文件——UDPClient.java和UDPServer.java来理解其工作原理。 首先,让我们来看看`UDPServer.java`。服务器端通常负责监听特定的端口,接收...
1. **socket编程**:服务器端需要创建一个UDP套接字,使用`socket()`函数创建套接字,`bind()`函数绑定本地IP和端口,然后用`recvfrom()`函数接收来自客户端的数据。 2. **数据包处理**:接收到的数据通常以字节流...
这个简单的JAVA-JAIN-SIP客户端示例展示了如何利用该库与SIP服务器进行交互,实现登录和发起呼叫的基本功能。SIP是一种互联网协议,常用于多媒体通信,如VoIP电话、视频会议等。 首先,我们要理解JAIN SIP(Java ...
1. **面向连接的通信**:TCP在进行数据传输前,会先建立连接,确保通信双方都能正常收发数据,这与UDP(用户数据报协议)的无连接通信方式不同。 2. **C#编程语言**:这是一个广泛应用于Windows平台的面向对象的...
以下是一个简单的UDP服务器示例: ```java import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetSocketAddress; public class UDPServer { ...
Java Netty是一个高性能、异步事件驱动的网络应用程序框架,常用于开发高效的网络服务,包括TCP、UDP等网络协议的应用。在"基于Java Netty的UDP客户端声呐数据对接"项目中,我们主要关注如何利用Netty处理UDP通信,...
例如,以下是一个简单的Java UDP客户端和服务器端示例: ```java // 客户端 public class UDPSender { public static void main(String[] args) throws Exception { String message = "Hello, Oracle!"; byte[] ...
总的来说,Java UDP实现服务器客户端大小写的转换是一个基础的网络编程示例,它涉及到网络套接字的创建、数据的收发以及基本的字符串操作。通过这个例子,开发者可以更好地理解网络编程的基本概念,为后续更复杂的...
在IT行业中,网络编程是不可或缺的一部分,...总之,理解并掌握UDP服务器和客户端的多线程编程是提升网络应用性能的关键,也是IT开发者必备的技能之一。通过实践和不断学习,你可以更好地应对各种复杂的网络编程挑战。
综上所述,实现基于Java的UDP服务器客户端通信涉及多个层面,包括Socket编程、数据封装、广播通信以及心跳机制等。理解这些概念和技术对于开发网络应用至关重要。通过`UDPserver`这样的项目,开发者可以实践这些知识...
本篇将详细介绍如何使用Java语言来实现基于UDP的客户端与服务器端通信。 首先,我们要了解UDP的基本原理。UDP不建立连接,而是直接发送数据报,每个数据报包含完整的源地址和目的地址,因此可以由任何节点发送到...
相反,C/S模式则是传统的客户端-服务器架构,其中一部分设备作为服务器提供服务,而另一部分设备作为客户端请求服务。在C/S模式的聊天室中,所有用户都连接到同一台或一组服务器,由服务器处理并转发消息。这种方式...
它是一个开源的Java库,广泛应用于服务器和客户端的开发,尤其在处理高并发、低延迟的网络服务时,Netty的表现尤为突出。Netty的核心是基于NIO(非阻塞I/O)和EventLoop事件驱动模型,这使得它能够在单线程或多线程...
* UDP服务器 * <p> UDP说明: * <p>UDP是无连接的通信协议,本质上不分服务端和客户端,两个段都可以对方当作服务器。 * <p> Java版本的可使用DatagramSocket接口实现,关键函数说明: * <p> .bind(): 表示监听...