当前位置:  开发笔记 > 编程语言 > 正文

Java:多线程和UDP套接字编程

如何解决《Java:多线程和UDP套接字编程》经验,为你挑选了1个好方法。

我是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那么有用.

否则你的方法是正确的......但我仍然建议你查看一些例子.



1> Kiril..:

首先要做的是:根据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那么有用.

否则你的方法是正确的......但我仍然建议你查看一些例子.


http://www.developer.com/java/ent/article.php/3645111/Java-5s-BlockingQueue.htm - Doug Lea的'简单服务器'
推荐阅读
echo7111436
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有