实现功能如下: 如服务器启动监听线程后,一直在监听某一设置端口
现在是要改变监听的端口,该如何去实现?类似网络点对点通讯实现

解决方案 »

  1.   

    这个怎么讲...?
    我现在就是DatagramSocket recvSocket= new DatagramSocket(5001);
    把原来的端口关掉是: recvSocket.disconnect(); 
    还是我上面的直接把该接收线程强制关掉,再重新创建?
      

  2.   

    java2000_net 说的没看明白呀,能否给个例子
    1、配置文件
    原线程定时检查文件中配置的端口号,如果改变了就使用新端口
    2、原线程实现一个改变监听端口的方法并做好同步
    public class myThread extends Thread{
            int port=0;
            int oldport=0;
            boolean isChanged=false;
            boolean canChange=false;
            public  synchronized boolean setPort(int port){
                while (true)
                {
                    if (canChange)
                    {
                        isChanged = true;
                        oldport=this.port;
                        this.port = port;
                        return true;
                    }
                    else
                    {
                        try
                        {
                            sleep(1000);
                        }
                        catch (InterruptedException e)
                        {
                            e.printStackTrace();
                            return false;
                        }
                    }
                }
            }
            public void run(){
                boolean goon=true;
                while(goon){
                    try
                    {
                        sleep(1000);
                        canChange=false;
                        if(isChanged){
                            stopOldport();
                            isChanged=false;
                        }
                        listern();
                        canChange=true;
                    }
                    catch (InterruptedException e)
                    {
                        e.printStackTrace();
                        goon=false;
                    }
                }
            }
            private void stopOldport()
            {
                //your code   
            }
            private void listern(){
                //your code
            }
        }
      

  3.   

    答:我都不明白,一个简单的问题,为什么都要搞得那么的复杂。
    1)注意:楼主的网络通信是UDP通信。
    2)因此:楼主在使用:ds.receive(UDP)包时,为了让接受线程不能一直在等待,应在创建DatagramSocket之后,立即使用:ds.setSoTimeout(毫秒)超时选项。时间一到,ds.receive()就抛出java.net.SocketTimeoutException,接收数据的线程就不会一直在等待。
    3)楼主随时可用:new DatagramSocket(port)打开新的监听端口号。老的监听端口号,若想不用时,可直接在接收数据的线程超时或数据处理之后,直接关闭就行了。(不过此时:没有接到端口号改变的客户机,数据将都发错了。)怎么办?可在改变端口号之前,留一个缓冲时间,在这个时间段,老端口继续接收数据,但同时发回响应UDP包给客户机,通知它“端口号”将改变就行了。
    4)补充说明:对于楼主的ds.disconnect()方法,看来楼主错用了。ds.disconnect()方法是用于关闭“连接型”UDP的,不是关闭“Socket”监听的。而是只能用于“客户机方”的。
      

  4.   

    这是我的接收线程类,负责数据的接收,同时里面调用了对接收数据的解析方法,并将解析后的数据显示到对应的文本区域内package comm;import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.SocketException;
    import java.util.Date;import ui.MainFrame;/**
     * 接收信息线程类
     * @author HUHG
     *
     */
    public class RecvThread extends Thread {
    private MainFrame mainFrame;
    private DatagramSocket dataSocket;
    private DatagramPacket dataPacket;
    private int port;

    //设置返回字符串信息,没有返回信息时返回NO INFORMATION
    private String recvString= "NO INFORMATION";
    public RecvThread(MainFrame mainFrame){
    this.mainFrame= mainFrame;
    this.port= 5001;
    }
    public RecvThread(int port){
    this.port= port;
    }
    public RecvThread(MainFrame mainFrame, int port){
    this.mainFrame= mainFrame;
    this.port= port;
    }
    /*
     * (non-Javadoc)
     * @see java.lang.Thread#run()
     */
    public void run(){
    try{
    dataSocket= new DatagramSocket(port);
    }catch(SocketException e){
    e.printStackTrace();
    }
    while(true){
    try{
    byte[] data= new byte[1024];
    dataPacket= new DatagramPacket(data,1024);
    dataSocket.receive(dataPacket);                                recvString= ParseData.parse(dataPacket, this.mainFrame.getID(), (byte)(this.mainFrame.getCom()),this.mainFrame.isFilterFlag());

    this.mainFrame.getRecvArea().append(new Date()+ "\n    "+ recvString+ "\n"); //将接收返回信息显示到显示文本区域
    }catch(SocketException e){
    e.printStackTrace();
    }catch(IOException ex){
    ex.printStackTrace();
    }
    }
    }

    /**
     * 返回接收到的数据信息字符串
     * @return String  返回接收的返回信息
     */
    public String recv(){
    return recvString;
    } /**
     * @param args
     */
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    }
    /**
     * 返回接收线程的监听端口
     * @return
     */
    public int getPort() {
    return port;
    }

    /**
     * 设置接收线程的监听端口
     * @param port
     */
    public void setPort(int port) {
    this.port = port;
    }}
      

  5.   

    答:原来的线程不要去关闭它,当然你想关就关吧。完全可以使用原来的线程:若读操作超时,您想继续在老的端口上监听收包,你就继续调:ds.receive(UDP包),若想换一个端口号,你就关闭老的socket,(ds.close())然后,在同一个线程中,创建一个新的DatagramSocket(新端口号),用ds.receive(UDP包)接收。也可以
    新创建一个线程,在其中创建一个新的DatagramSocket(新端口号),用ds.receive(UDP包)接收。老的那个线程在老的端口号上继续监听一段时间(这个时间就是你的过渡时间,在这个过渡时间,你通过发UDP包通知你的客户机端口号到几月几号要变了,让他们有个准备时间),这个过渡时间一过,你再关闭这个老的线程(及其老的ds.close())以上仅供你参考