我是Java中多线程和套接字编程的新手.我想知道实现2个线程的最佳方法是什么 - 一个用于接收套接字,另一个用于发送套接字.如果我想做的事听起来很荒谬,请告诉我原因!该代码很大程度上受到Sun在线教程的启发.我想使用多播套接字,以便我可以使用多播组.
class Server extends Thread { static protected MulticastSocket socket = null; protected BufferedReader in = null; public InetAddress group; private static class Receive implements Runnable { public void run() { try { byte[] buf = new byte[256]; DatagramPacket pkt = new DatagramPacket(buf,buf.length); socket.receive(pkt); String received = new String(pkt.getData(),0,pkt.getLength()); System.out.println("From server@" + received); Thread.sleep(1000); } catch (IOException e) { System.out.println("Error:"+e); } catch (InterruptedException e) { System.out.println("Error:"+e); } } } public Server() throws IOException { super("server"); socket = new MulticastSocket(4446); group = InetAddress.getByName("239.231.12.3"); socket.joinGroup(group); } public void run() { while(1>0) { try { byte[] buf = new byte[256]; DatagramPacket pkt = new DatagramPacket(buf,buf.length); //String msg = reader.readLine(); String pid = ManagementFactory.getRuntimeMXBean().getName(); buf = pid.getBytes(); pkt = new DatagramPacket(buf,buf.length,group,4446); socket.send(pkt); Thread t = new Thread(new Receive()); t.start(); while(t.isAlive()) { t.join(1000); } sleep(1); } catch (IOException e) { System.out.println("Error:"+e); } catch (InterruptedException e) { System.out.println("Error:"+e); } } //socket.close(); } public static void main(String[] args) throws IOException { new Server().start(); //System.out.println("Hello"); } }
Kiril.. 9
首先要做的是:根据Java命名约定,您的类应以大写字母开头:
类名应该是名词,大小写混合,每个内部单词的首字母大写.尽量保持您的类名简单和描述性.使用整个单词 - 避免缩略语和缩写(除非缩写比长格式更广泛使用,例如URL或HTML).
第二: 尝试将代码分解为连贯的部分,并围绕您正在处理的一些常见功能组织它们......可能围绕您正在编程的功能或模型.
服务器的(基本)模型是它唯一能做的就是接收套接字连接......服务器依靠处理程序来处理这些连接,就是这样.如果您尝试构建该模型,它将看起来像这样:
class Server{ private final ServerSocket serverSocket; private final ExecutorService pool; public Server(int port, int poolSize) throws IOException { serverSocket = new ServerSocket(port); pool = Executors.newFixedThreadPool(poolSize); } public void serve() { try { while(true) { pool.execute(new Handler(serverSocket.accept())); } } catch (IOException ex) { pool.shutdown(); } } } class Handler implements Runnable { private final Socket socket; Handler(Socket socket) { this.socket = socket; } public void run() { // receive the datagram packets } }
第三:我建议你看一些现有的例子.
多线程客户端/服务器应用程序:http:
//www.ase.md/~aursu/ClientServerThreads.html
Doug Lea:
http://www.developer.com/java/ent/article.php/3645111/Java-5s-BlockingQueue.htm(感谢John)
http://gee.cs.oswego.edu/dl/cpj /index.html (仍然无法找到确切的示例,但它在某处......如果你觉得勇敢地查看他的allcode.java文件).
并发实践示例:http:
//www.javaconcurrencyinpractice.com/listings.html
Java Concurrency教程:http:
//java.sun.com/docs/books/tutorial/essential/concurrency/
每条评论更新:
好的Ravi,您的代码存在一些重大问题以及一些小问题:
我假设Receive
该类是您的客户端...您应该将其作为一个单独的程序(具有自己的主类),并同时运行您的服务器和多个客户端.从您的服务器为您发送的每个新UDP包生成一个新的"客户端线程"是一个令人不安的想法(大问题).
在创建客户端应用程序时,应该使其在自己的while
循环中运行接收代码(次要问题),例如:
public class Client extends Thread { public Client(/*..*/) { // initialize your client } public void run() { while(true) { // receive UDP packets // process the UDP packets } } public static void main(String[] args) throws IOException { // start your client new Client().start(); } }
你应该只需要每个客户端一个线程和每个服务器一个线程(你在技术上甚至没有单独的线程,因为main有自己的线程),所以你可能找不到ExecutorService
那么有用.
否则你的方法是正确的......但我仍然建议你查看一些例子.
首先要做的是:根据Java命名约定,您的类应以大写字母开头:
类名应该是名词,大小写混合,每个内部单词的首字母大写.尽量保持您的类名简单和描述性.使用整个单词 - 避免缩略语和缩写(除非缩写比长格式更广泛使用,例如URL或HTML).
第二: 尝试将代码分解为连贯的部分,并围绕您正在处理的一些常见功能组织它们......可能围绕您正在编程的功能或模型.
服务器的(基本)模型是它唯一能做的就是接收套接字连接......服务器依靠处理程序来处理这些连接,就是这样.如果您尝试构建该模型,它将看起来像这样:
class Server{ private final ServerSocket serverSocket; private final ExecutorService pool; public Server(int port, int poolSize) throws IOException { serverSocket = new ServerSocket(port); pool = Executors.newFixedThreadPool(poolSize); } public void serve() { try { while(true) { pool.execute(new Handler(serverSocket.accept())); } } catch (IOException ex) { pool.shutdown(); } } } class Handler implements Runnable { private final Socket socket; Handler(Socket socket) { this.socket = socket; } public void run() { // receive the datagram packets } }
第三:我建议你看一些现有的例子.
多线程客户端/服务器应用程序:http:
//www.ase.md/~aursu/ClientServerThreads.html
Doug Lea:
http://www.developer.com/java/ent/article.php/3645111/Java-5s-BlockingQueue.htm(感谢John)
http://gee.cs.oswego.edu/dl/cpj /index.html (仍然无法找到确切的示例,但它在某处......如果你觉得勇敢地查看他的allcode.java文件).
并发实践示例:http:
//www.javaconcurrencyinpractice.com/listings.html
Java Concurrency教程:http:
//java.sun.com/docs/books/tutorial/essential/concurrency/
每条评论更新:
好的Ravi,您的代码存在一些重大问题以及一些小问题:
我假设Receive
该类是您的客户端...您应该将其作为一个单独的程序(具有自己的主类),并同时运行您的服务器和多个客户端.从您的服务器为您发送的每个新UDP包生成一个新的"客户端线程"是一个令人不安的想法(大问题).
在创建客户端应用程序时,应该使其在自己的while
循环中运行接收代码(次要问题),例如:
public class Client extends Thread { public Client(/*..*/) { // initialize your client } public void run() { while(true) { // receive UDP packets // process the UDP packets } } public static void main(String[] args) throws IOException { // start your client new Client().start(); } }
你应该只需要每个客户端一个线程和每个服务器一个线程(你在技术上甚至没有单独的线程,因为main有自己的线程),所以你可能找不到ExecutorService
那么有用.
否则你的方法是正确的......但我仍然建议你查看一些例子.