JAVA网络编程服务器多线程接受套接字,如何能使服务器的静态常量,与客户端的数据进行同步?

服务器Server
客户端CLient
Server静态常量num
创建服务器,ServerSocket的端口号为8000,连接套接字。
每创建一个客户端,客户端就创建一个Socket,端口号为8000,与服务器进行连接,与此同时,客户端新建ServerSocket,端口号为3000+Server.num,连接套接字。
服务器与客户端连接后,服务器新建子线程Handler。
子线程Handler,新建ServerSocket,端口号为2000+Server.num,连接套接字。

每当有一个子线程创建,主线程都会加入一个子线程创建的对话界面(显示框,输入框,发送按钮)的选项卡
每当创建一个客户端,客户端都会创建一个对话界面

点击发送时,Hanlder会创建Socket,端口号为3000+Server.num。客户端会创建Socket,端口号为2000+Server.num

这是前提,现在我运行程序,但是当我每当创建一个客户端时,Server.num都不会改变,不知道怎么回事,急求大神解答,感激不尽!

以下是源代码,这里我讲Server.num抽离出去单独做成一个类NUM,每次Handler创建后,调用该类的增加函数numAdd():

服务器代码:

package NewPackage;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class Server {
private ServerSocket serverSocket;
private int PORT = 8000;
private Thread workThread;
private static MyServer server;
public static ArrayList solist = new ArrayList();
public static ArrayList ctlist = new ArrayList();

public Server() throws Exception {
    serverSocket = new ServerSocket(PORT);
}

public void service() {
    while (true) {
        Socket socket = null;
        try {
            String s;
            int num = NUM.num;
            NUM.numadd();
            socket = serverSocket.accept();
            System.out.println(num + 2000);
            workThread = new Thread(new Handler(num + 2000, MyServer.jp));
            workThread.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

public static void main(String args[]) throws Exception {
    server = new MyServer();
    server.CreateGUI();
    new Server().service();
}

}

服务器的界面代码:
package NewPackage;

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;

public class MyServer extends JFrame {

private static final long serialVersionUID = 1L;
static JTextArea contentjta;
static JScrollPane contentscroll;
static JTextArea inputjta;
static JScrollPane inputscroll;
static JButton button;
static JPanel jpanel;
static JTabbedPane jp;

MyServer() {
    super("Server Window");
}

void CreateGUI() {
    jp = new JTabbedPane();
    this.add(jp, BorderLayout.CENTER); // 将选项卡窗体添加到 主窗体上去
    this.setSize(400, 400);
    this.setLocation(400, 200);
    this.setVisible(true);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

}

子线程Handler

package NewPackage;

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;

public class Handler implements Runnable, ActionListener {
private Socket socket;
private PrintWriter pw;
private int order;
private ServerSocket svs;
private MyClient client;
static JTextArea contentjta;
static JScrollPane contentscroll;
static JTextArea inputjta;
static JScrollPane inputscroll;
static JButton button;
static JPanel jpanel;
static JTabbedPane jp;
private BufferedReader br;

public Handler(int n, JTabbedPane jp) {
    try {
        this.jp = jp;
        // this.socket = socket;
        // System.out.println("handler" + socket.getLocalPort());
        order = n ;
        // JOptionPane.showInputDialog(this, order);
        System.out.println("Handler" + order);
        svs = new ServerSocket(order + 1000);
        createTab();
    } catch (Exception e) {
        e.printStackTrace();
    }

}

private PrintWriter getWriter(Socket socket) throws IOException {
    OutputStream socketOut = socket.getOutputStream();
    return new PrintWriter(socketOut, true);
}

private BufferedReader getReader(Socket socket) throws IOException {
    InputStream socketln = socket.getInputStream();
    return new BufferedReader(new InputStreamReader(socketln));
}

void createTab() {
    JPanel chat = new JPanel(new BorderLayout());

    contentjta = new JTextArea(10, 30);
    contentjta.setTabSize(4);
    contentjta.setFont(new Font("楷体", Font.BOLD, 16));
    contentjta.setEditable(false);

    inputjta = new JTextArea(10, 30);
    inputjta.setTabSize(4);
    inputjta.setFont(new Font("楷体", Font.BOLD, 16));
    inputjta.setEditable(true);

    contentscroll = new JScrollPane(contentjta);
    contentscroll
            .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    contentscroll
            .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

    inputscroll = new JScrollPane(inputjta);
    inputscroll
            .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    inputscroll
            .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

    jpanel = new JPanel();
    button = new JButton("发送");
    button.addActionListener(this);

    jpanel.setLayout(new GridLayout(1, 1));
    jpanel.add(button);

    chat.add(contentscroll, BorderLayout.NORTH);
    chat.add(inputscroll, BorderLayout.CENTER);
    chat.add(jpanel, BorderLayout.SOUTH);
    jp.add("aa", chat);
    jp.setFont(new Font("宋体", Font.BOLD, 20));

}

public void run() {
    try {
        // 接受信息
        while (true) {
            Socket socket = svs.accept();
            br = getReader(socket);
            pw = getWriter(socket);
            String msg = null;
            String s = "";
            while ((msg = br.readLine()) != null) {
                s += msg;
                if ((msg.equals("bye")))
                    break;
            }
            contentjta.setText(s);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

@Override
public void actionPerformed(ActionEvent e) {
    Object o = e.getSource();
    if (o == button) {
        try {
            Socket so = new Socket("localhost", order);
            OutputStream out = so.getOutputStream();
            PrintStream pout = new PrintStream(out);
            pout.print(inputjta.getText());
            inputjta.setText("");
            out.flush();
            out.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }
}

}

字数限制,以下是其他内容

客户端代码:
package NewPackage;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class Client {
static int PORT = 2000;

public static void main(String[] args) {
    int num = 1;
    MyClient client = new MyClient(3000 + num);
    client.CreateGUI();
    try {
        System.out.println(PORT + num);
        ServerSocket serversocket = new ServerSocket(PORT + num);
        NUM.numadd();
        while (true) {
            Socket socket = serversocket.accept();
            BufferedReader br = new BufferedReader(new InputStreamReader(
                    socket.getInputStream()));
            String msg;
            String s = "";
            while (((msg = br.readLine()) != null)) {
                s += msg;
                if (msg.equals("bye"))
                    break;
            }
            System.out.println(s);
            client.getContentjta().setText(s);
        }
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

}

客户端界面代码:
package NewPackage;

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class MyClient extends JFrame implements ActionListener {

private static final long serialVersionUID = 1L;
static JTextArea contentjta;
static JScrollPane contentscroll;
static JTextArea inputjta;
static JScrollPane inputscroll;
static JButton button;
static JPanel jpanel;
private Socket socket;
private int order;

public static JTextArea getContentjta() {
    return contentjta;
}

public MyClient(int n) {
    super("Client Window");
    order = n;
}

void CreateGUI() {
    // System.out.println("MyClient" + order);
    try {
        socket = new Socket("localhost", 8000);
        socket.close();
    } catch (Exception e1) {
        e1.printStackTrace();
    }
    JPanel chat = new JPanel(new BorderLayout());
    contentjta = new JTextArea(10, 30);
    contentjta.setTabSize(4);
    contentjta.setFont(new Font("楷体", Font.BOLD, 16));
    contentjta.setEditable(false);

    inputjta = new JTextArea(10, 30);
    inputjta.setTabSize(4);
    inputjta.setFont(new Font("楷体", Font.BOLD, 16));
    inputjta.setEditable(true);

    contentscroll = new JScrollPane(contentjta);
    contentscroll
            .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    contentscroll
            .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

    inputscroll = new JScrollPane(inputjta);
    inputscroll
            .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    inputscroll
            .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

    jpanel = new JPanel();
    button = new JButton("发送");
    button.addActionListener(this);

    jpanel.setLayout(new GridLayout(1, 1));
    jpanel.add(button);

    chat.add(contentscroll, BorderLayout.NORTH);
    chat.add(inputscroll, BorderLayout.CENTER);
    chat.add(jpanel, BorderLayout.SOUTH);

    this.setSize(400, 400);
    this.setLocation(400, 200);
    this.setVisible(true);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.add(chat);
}

@Override
public void actionPerformed(ActionEvent e) {
    Object o = e.getSource();
    if (o == button) {
        try {
            Socket so = new Socket("localhost", order);
            OutputStream out = so.getOutputStream();
            PrintStream pout = new PrintStream(out);
            pout.print(inputjta.getText());
            inputjta.setText("");
            out.flush();
            out.close();

        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }
}

}

NUM类
package NewPackage;

public class NUM {
public static int num = 0;
static void numadd(){
num++;
}
}