SOCKET之TCP

SOCKET之TCP

socket连接中分为服务端和客户端,Java中使用socket建立TCP连接很方便。

建立连接

Server端
监听本地某个端口,只需两句代码就行

ServerSocket serverSocket = new ServerSocket(PORT);
Socket task = serverSocket.accept();

Client 端

InetSocketAddress addr = new InetSocketAddress("127.0.0.1",10001);
Socket socket = new Socket();
socket.connect(addr);
 

这样就完成了tcp的监听和连接了。
本文完。。。。。。。。。。。

发送与接收

建立连接确实已经完成了,但是建立socket是需要进行通信的。那么如何进行发送和接收呢?只需要获取其输入输出流,然后按照平常的方式进行读写操作即可。
服务端和客户端一样

output = new ObjectOutputStream(socket.getOutputStream());
input = new ObjectInputStream(socket.getInputStream());

如果需要发送信息

output.writeUTF("server send message!");
output.flush();

如果需要读取消息,注意读取消息是阻塞的。

String re = input.readUTF();

通信完成之后,注意释放资源

input.close();
output.close();
socket.close();

Server处理多个客户端

服务端监听了一个端口,我们通常不止和一个客户端通信,但是等待客户端连接和读取消息是阻塞的。那么我们很自然就想到了使用多线程来处理,多线程可以使用手动新建线程的方法实现,也可以使用多线程实现。为了提高性能,线程池是个不错的选择。

线程池

我们知道Java创建线程池很简单,有Executors可以直接创建线程,提供了多种创建线程池的方式,如

Executors.newSingleThreadExecutor();
Executors.newCachedThreadPool();
Executors.newFixedThreadPool(2);
Executors.newScheduledThreadPool(2);

其中最后一种是支持定时及周期性任务执行。
延迟执行示例代码如下,表示上一次执行完成延时3秒后执行

schedule(new Runnable(),3, TimeUnit.SECONDS); 

定期执行示例代码如下,表示延迟1秒后每3秒执行一次。

scheduleAtFixedRate(new Runnable(), 1, 3, TimeUnit.SECONDS);

对于前面三种线程池,用Executors创建线程池,其实就是就是返回new ThreadPoolExecutor(),只是参数不一样。
例如newSingleThreadExecutor里面的方法:

public static ExecutorService newSingleThreadExecutor() {    
    return new FinalizableDelegatedExecutorService        (
        new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
}

ThreadPoolExecutor 构造函数的参数含义如下,后面两个是可选参数,有默认值:
corePoolSize:指定了线程池中的线程数量,它的数量决定了添加的任务是开辟新的线程去执行,还是放到workQueue任务队列中去;
maximumPoolSize:指定了线程池中的最大线程数量,这个参数会根据你使用的workQueue任务队列的类型,决定线程池会开辟的最大线程数量;
keepAliveTime:当线程池中空闲线程数量超过corePoolSize时,多余的线程会在多长时间内被销毁;unit:keepAliveTime的单位
workQueue:任务队列,被添加到线程池中,但尚未被执行的任务;它一般分为直接提交队列、有界任务队列、无界任务队列、优先任务队列几种;
threadFactory:线程工厂,用于创建线程,一般用默认即可;
handler:拒绝策略;当任务太多来不及处理时,如何拒绝任务;

多线程讲到这里,我们开始继续server加入线程池的处理。

每个客户端进行单独处理

首先,我们需要多线程处理,创建线程池

ThreadPoolExecutor pool  = new ThreadPoolExecutor(0, MaxClient,        
            60L, TimeUnit.SECONDS,        
            new SynchronousQueue<Runnable>());

其中,MaxClient表示我们可以最多接收的客户端。
server的方法如下:

try (ServerSocket serverSocket = new ServerSocket(PORT)) {     
    while (true) {        
        task = serverSocket.accept();        
        try {           
            pool.execute(new ServerTask(task));              
        } catch (RejectedExecutionException e) {                
            if (task != null) {   task.close(); }        
        }    
    }
}

server中,accept会不断等待新的客户端,如果有新的客户端进来,就提交到线程池进行通信。ServerTask 就是定义对应的通信方式,阻塞读取信息,如果有消息过来,就把收到的消息发送回去。如果客户端多于MaxClient,就会抛出RejectedExecutionException,定义如下:

class ServerTask implements Runnable {   
    private Socket task = null;    
    public ServerTask(Socket task) {       
        this.task = task;    
    }    
    @Override   
    public void run() {        
    try (                
        ObjectOutputStream output = new 
        ObjectOutputStream(task.getOutputStream());               
        ObjectInputStream input = new 
        ObjectInputStream(task.getInputStream());        ) {            
            while (true) {                
                String msg = input.readUTF();                
                output.writeUTF("server已经接收到:" + msg);                
                output.flush();            
            }        
        } 
    catch (IOException e) {            
        System.out.println("已经断开连接");        }    
    }
}
 

客户端输入发送

客户端进行输入后发送并接收服务端发送过来的消息,代码实现如下

 
output = new ObjectOutputStream(socket.getOutputStream());
input = new ObjectInputStream(socket.getInputStream());

Scanner scanner = new Scanner(System.in);
while(true) {    
    String msg = scanner.nextLine();    
    output.writeUTF(msg);    
    output.flush();    
    //String re = input.readUTF();   
}

具体代码可以参考github项目,在目录:com/okayjam/net/socket/tcp下
https://github.com/weiguang/JamJavaUtil

%23%20SOCKET%E4%B9%8BTCP%0Asocket%E8%BF%9E%E6%8E%A5%E4%B8%AD%E5%88%86%E4%B8%BA%E6%9C%8D%E5%8A%A1%E7%AB%AF%E5%92%8C%E5%AE%A2%E6%88%B7%E7%AB%AF%EF%BC%8CJava%E4%B8%AD%E4%BD%BF%E7%94%A8socket%E5%BB%BA%E7%AB%8BTCP%E8%BF%9E%E6%8E%A5%E5%BE%88%E6%96%B9%E4%BE%BF%E3%80%82%0A%0A%0A%23%23%20%E5%BB%BA%E7%AB%8B%E8%BF%9E%E6%8E%A5%0A%20**Server%E7%AB%AF**%0A%E7%9B%91%E5%90%AC%E6%9C%AC%E5%9C%B0%E6%9F%90%E4%B8%AA%E7%AB%AF%E5%8F%A3%EF%BC%8C%E5%8F%AA%E9%9C%80%E4%B8%A4%E5%8F%A5%E4%BB%A3%E7%A0%81%E5%B0%B1%E8%A1%8C%0A%60%60%60%0AServerSocket%20serverSocket%20%3D%20new%20ServerSocket(PORT)%3B%0ASocket%20task%20%3D%20serverSocket.accept()%3B%0A%60%60%60%0A%0A**Client%20%E7%AB%AF**%0A%60%60%60%0AInetSocketAddress%20addr%20%3D%20new%20InetSocketAddress(%22127.0.0.1%22%2C10001)%3B%0ASocket%20socket%20%3D%20new%20Socket()%3B%0Asocket.connect(addr)%3B%0A%60%60%60%0A%E8%BF%99%E6%A0%B7%E5%B0%B1%E5%AE%8C%E6%88%90%E4%BA%86tcp%E7%9A%84%E7%9B%91%E5%90%AC%E5%92%8C%E8%BF%9E%E6%8E%A5%E4%BA%86%E3%80%82%0A%E6%9C%AC%E6%96%87%E5%AE%8C%E3%80%82%E3%80%82%E3%80%82%E3%80%82%E3%80%82%E3%80%82%E3%80%82%E3%80%82%E3%80%82%E3%80%82%E3%80%82%0A%0A%0A%0A%23%23%20%E5%8F%91%E9%80%81%E4%B8%8E%E6%8E%A5%E6%94%B6%0A%E5%BB%BA%E7%AB%8B%E8%BF%9E%E6%8E%A5%E7%A1%AE%E5%AE%9E%E5%B7%B2%E7%BB%8F%E5%AE%8C%E6%88%90%E4%BA%86%EF%BC%8C%E4%BD%86%E6%98%AF%E5%BB%BA%E7%AB%8Bsocket%E6%98%AF%E9%9C%80%E8%A6%81%E8%BF%9B%E8%A1%8C%E9%80%9A%E4%BF%A1%E7%9A%84%E3%80%82%E9%82%A3%E4%B9%88%E5%A6%82%E4%BD%95%E8%BF%9B%E8%A1%8C%E5%8F%91%E9%80%81%E5%92%8C%E6%8E%A5%E6%94%B6%E5%91%A2%3F%E5%8F%AA%E9%9C%80%E8%A6%81%E8%8E%B7%E5%8F%96%E5%85%B6%E8%BE%93%E5%85%A5%E8%BE%93%E5%87%BA%E6%B5%81%EF%BC%8C%E7%84%B6%E5%90%8E%E6%8C%89%E7%85%A7%E5%B9%B3%E5%B8%B8%E7%9A%84%E6%96%B9%E5%BC%8F%E8%BF%9B%E8%A1%8C%E8%AF%BB%E5%86%99%E6%93%8D%E4%BD%9C%E5%8D%B3%E5%8F%AF%E3%80%82%0A%E6%9C%8D%E5%8A%A1%E7%AB%AF%E5%92%8C%E5%AE%A2%E6%88%B7%E7%AB%AF%E4%B8%80%E6%A0%B7%0A%60%60%60%0Aoutput%20%3D%20new%20ObjectOutputStream(socket.getOutputStream())%3B%0Ainput%20%3D%20new%20ObjectInputStream(socket.getInputStream())%3B%0A%60%60%60%0A%E5%A6%82%E6%9E%9C%E9%9C%80%E8%A6%81%E5%8F%91%E9%80%81%E4%BF%A1%E6%81%AF%0A%60%60%60%0Aoutput.writeUTF(%22server%20send%20message!%22)%3B%0Aoutput.flush()%3B%0A%60%60%60%0A%E5%A6%82%E6%9E%9C%E9%9C%80%E8%A6%81%E8%AF%BB%E5%8F%96%E6%B6%88%E6%81%AF%EF%BC%8C%E6%B3%A8%E6%84%8F%E8%AF%BB%E5%8F%96%E6%B6%88%E6%81%AF%E6%98%AF%E9%98%BB%E5%A1%9E%E7%9A%84%E3%80%82%0A%60%60%60%0AString%20re%20%3D%20input.readUTF()%3B%0A%60%60%60%0A%E9%80%9A%E4%BF%A1%E5%AE%8C%E6%88%90%E4%B9%8B%E5%90%8E%EF%BC%8C%E6%B3%A8%E6%84%8F%E9%87%8A%E6%94%BE%E8%B5%84%E6%BA%90%0A%60%60%60%0Ainput.close()%3B%0Aoutput.close()%3B%0Asocket.close()%3B%0A%60%60%60%0A%0A%23%23%20Server%E5%A4%84%E7%90%86%E5%A4%9A%E4%B8%AA%E5%AE%A2%E6%88%B7%E7%AB%AF%0A%E6%9C%8D%E5%8A%A1%E7%AB%AF%E7%9B%91%E5%90%AC%E4%BA%86%E4%B8%80%E4%B8%AA%E7%AB%AF%E5%8F%A3%EF%BC%8C%E6%88%91%E4%BB%AC%E9%80%9A%E5%B8%B8%E4%B8%8D%E6%AD%A2%E5%92%8C%E4%B8%80%E4%B8%AA%E5%AE%A2%E6%88%B7%E7%AB%AF%E9%80%9A%E4%BF%A1%EF%BC%8C%E4%BD%86%E6%98%AF%E7%AD%89%E5%BE%85%E5%AE%A2%E6%88%B7%E7%AB%AF%E8%BF%9E%E6%8E%A5%E5%92%8C%E8%AF%BB%E5%8F%96%E6%B6%88%E6%81%AF%E6%98%AF%E9%98%BB%E5%A1%9E%E7%9A%84%E3%80%82%E9%82%A3%E4%B9%88%E6%88%91%E4%BB%AC%E5%BE%88%E8%87%AA%E7%84%B6%E5%B0%B1%E6%83%B3%E5%88%B0%E4%BA%86%E4%BD%BF%E7%94%A8%E5%A4%9A%E7%BA%BF%E7%A8%8B%E6%9D%A5%E5%A4%84%E7%90%86%EF%BC%8C%E5%A4%9A%E7%BA%BF%E7%A8%8B%E5%8F%AF%E4%BB%A5%E4%BD%BF%E7%94%A8%E6%89%8B%E5%8A%A8%E6%96%B0%E5%BB%BA%E7%BA%BF%E7%A8%8B%E7%9A%84%E6%96%B9%E6%B3%95%E5%AE%9E%E7%8E%B0%EF%BC%8C%E4%B9%9F%E5%8F%AF%E4%BB%A5%E4%BD%BF%E7%94%A8%E5%A4%9A%E7%BA%BF%E7%A8%8B%E5%AE%9E%E7%8E%B0%E3%80%82%E4%B8%BA%E4%BA%86%E6%8F%90%E9%AB%98%E6%80%A7%E8%83%BD%EF%BC%8C%E7%BA%BF%E7%A8%8B%E6%B1%A0%E6%98%AF%E4%B8%AA%E4%B8%8D%E9%94%99%E7%9A%84%E9%80%89%E6%8B%A9%E3%80%82%0A%0A%23%23%23%20%E7%BA%BF%E7%A8%8B%E6%B1%A0%0A%E6%88%91%E4%BB%AC%E7%9F%A5%E9%81%93Java%E5%88%9B%E5%BB%BA%E7%BA%BF%E7%A8%8B%E6%B1%A0%E5%BE%88%E7%AE%80%E5%8D%95%EF%BC%8C%E6%9C%89Executors%E5%8F%AF%E4%BB%A5%E7%9B%B4%E6%8E%A5%E5%88%9B%E5%BB%BA%E7%BA%BF%E7%A8%8B%EF%BC%8C%E6%8F%90%E4%BE%9B%E4%BA%86%E5%A4%9A%E7%A7%8D%E5%88%9B%E5%BB%BA%E7%BA%BF%E7%A8%8B%E6%B1%A0%E7%9A%84%E6%96%B9%E5%BC%8F%EF%BC%8C%E5%A6%82%0A%60%60%60%0AExecutors.newSingleThreadExecutor()%3B%0AExecutors.newCachedThreadPool()%3B%0AExecutors.newFixedThreadPool(2)%3B%0AExecutors.newScheduledThreadPool(2)%3B%0A%60%60%60%0A%E5%85%B6%E4%B8%AD%E6%9C%80%E5%90%8E%E4%B8%80%E7%A7%8D%E6%98%AF%E6%94%AF%E6%8C%81%E5%AE%9A%E6%97%B6%E5%8F%8A%E5%91%A8%E6%9C%9F%E6%80%A7%E4%BB%BB%E5%8A%A1%E6%89%A7%E8%A1%8C%E3%80%82%0A%E5%BB%B6%E8%BF%9F%E6%89%A7%E8%A1%8C%E7%A4%BA%E4%BE%8B%E4%BB%A3%E7%A0%81%E5%A6%82%E4%B8%8B%2C%E8%A1%A8%E7%A4%BA%E4%B8%8A%E4%B8%80%E6%AC%A1%E6%89%A7%E8%A1%8C%E5%AE%8C%E6%88%90%E5%BB%B6%E6%97%B63%E7%A7%92%E5%90%8E%E6%89%A7%E8%A1%8C%0A%60%60%60%0Aschedule(new%20Runnable()%2C3%2C%20TimeUnit.SECONDS)%3B%20%0A%60%60%60%0A%0A%E5%AE%9A%E6%9C%9F%E6%89%A7%E8%A1%8C%E7%A4%BA%E4%BE%8B%E4%BB%A3%E7%A0%81%E5%A6%82%E4%B8%8B%EF%BC%8C%E8%A1%A8%E7%A4%BA%E5%BB%B6%E8%BF%9F1%E7%A7%92%E5%90%8E%E6%AF%8F3%E7%A7%92%E6%89%A7%E8%A1%8C%E4%B8%80%E6%AC%A1%E3%80%82%0A%60%60%60%0AscheduleAtFixedRate(new%20Runnable()%2C%201%2C%203%2C%20TimeUnit.SECONDS%EF%BC%89%3B%0A%60%60%60%0A%0A%E5%AF%B9%E4%BA%8E%E5%89%8D%E9%9D%A2%E4%B8%89%E7%A7%8D%E7%BA%BF%E7%A8%8B%E6%B1%A0%EF%BC%8C%E7%94%A8Executors%E5%88%9B%E5%BB%BA%E7%BA%BF%E7%A8%8B%E6%B1%A0%EF%BC%8C%E5%85%B6%E5%AE%9E%E5%B0%B1%E6%98%AF%E5%B0%B1%E6%98%AF%E8%BF%94%E5%9B%9Enew%20ThreadPoolExecutor()%EF%BC%8C%E5%8F%AA%E6%98%AF%E5%8F%82%E6%95%B0%E4%B8%8D%E4%B8%80%E6%A0%B7%E3%80%82%0A%E4%BE%8B%E5%A6%82newSingleThreadExecutor%E9%87%8C%E9%9D%A2%E7%9A%84%E6%96%B9%E6%B3%95%EF%BC%9A%0A%60%60%60%0Apublic%20static%20ExecutorService%20newSingleThreadExecutor()%20%7B%C2%A0%C2%A0%C2%A0%20%0A%20%20%20%20return%20new%20FinalizableDelegatedExecutorService%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20(%0A%20%20%20%20%20%20%20%20new%20ThreadPoolExecutor(1%2C%201%2C%200L%2C%20TimeUnit.MILLISECONDS%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20new%20LinkedBlockingQueue%3CRunnable%3E()))%3B%0A%7D%0A%0A%60%60%60%0A%0A%0AThreadPoolExecutor%20%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%E7%9A%84%E5%8F%82%E6%95%B0%E5%90%AB%E4%B9%89%E5%A6%82%E4%B8%8B%EF%BC%8C%E5%90%8E%E9%9D%A2%E4%B8%A4%E4%B8%AA%E6%98%AF%E5%8F%AF%E9%80%89%E5%8F%82%E6%95%B0%EF%BC%8C%E6%9C%89%E9%BB%98%E8%AE%A4%E5%80%BC%EF%BC%9A%0AcorePoolSize%3A%E6%8C%87%E5%AE%9A%E4%BA%86%E7%BA%BF%E7%A8%8B%E6%B1%A0%E4%B8%AD%E7%9A%84%E7%BA%BF%E7%A8%8B%E6%95%B0%E9%87%8F%EF%BC%8C%E5%AE%83%E7%9A%84%E6%95%B0%E9%87%8F%E5%86%B3%E5%AE%9A%E4%BA%86%E6%B7%BB%E5%8A%A0%E7%9A%84%E4%BB%BB%E5%8A%A1%E6%98%AF%E5%BC%80%E8%BE%9F%E6%96%B0%E7%9A%84%E7%BA%BF%E7%A8%8B%E5%8E%BB%E6%89%A7%E8%A1%8C%EF%BC%8C%E8%BF%98%E6%98%AF%E6%94%BE%E5%88%B0workQueue%E4%BB%BB%E5%8A%A1%E9%98%9F%E5%88%97%E4%B8%AD%E5%8E%BB%EF%BC%9B%0AmaximumPoolSize%3A%E6%8C%87%E5%AE%9A%E4%BA%86%E7%BA%BF%E7%A8%8B%E6%B1%A0%E4%B8%AD%E7%9A%84%E6%9C%80%E5%A4%A7%E7%BA%BF%E7%A8%8B%E6%95%B0%E9%87%8F%EF%BC%8C%E8%BF%99%E4%B8%AA%E5%8F%82%E6%95%B0%E4%BC%9A%E6%A0%B9%E6%8D%AE%E4%BD%A0%E4%BD%BF%E7%94%A8%E7%9A%84workQueue%E4%BB%BB%E5%8A%A1%E9%98%9F%E5%88%97%E7%9A%84%E7%B1%BB%E5%9E%8B%EF%BC%8C%E5%86%B3%E5%AE%9A%E7%BA%BF%E7%A8%8B%E6%B1%A0%E4%BC%9A%E5%BC%80%E8%BE%9F%E7%9A%84%E6%9C%80%E5%A4%A7%E7%BA%BF%E7%A8%8B%E6%95%B0%E9%87%8F%EF%BC%9B%0AkeepAliveTime%3A%E5%BD%93%E7%BA%BF%E7%A8%8B%E6%B1%A0%E4%B8%AD%E7%A9%BA%E9%97%B2%E7%BA%BF%E7%A8%8B%E6%95%B0%E9%87%8F%E8%B6%85%E8%BF%87corePoolSize%E6%97%B6%EF%BC%8C%E5%A4%9A%E4%BD%99%E7%9A%84%E7%BA%BF%E7%A8%8B%E4%BC%9A%E5%9C%A8%E5%A4%9A%E9%95%BF%E6%97%B6%E9%97%B4%E5%86%85%E8%A2%AB%E9%94%80%E6%AF%81%EF%BC%9Bunit%3AkeepAliveTime%E7%9A%84%E5%8D%95%E4%BD%8D%0AworkQueue%3A%E4%BB%BB%E5%8A%A1%E9%98%9F%E5%88%97%EF%BC%8C%E8%A2%AB%E6%B7%BB%E5%8A%A0%E5%88%B0%E7%BA%BF%E7%A8%8B%E6%B1%A0%E4%B8%AD%EF%BC%8C%E4%BD%86%E5%B0%9A%E6%9C%AA%E8%A2%AB%E6%89%A7%E8%A1%8C%E7%9A%84%E4%BB%BB%E5%8A%A1%EF%BC%9B%E5%AE%83%E4%B8%80%E8%88%AC%E5%88%86%E4%B8%BA%E7%9B%B4%E6%8E%A5%E6%8F%90%E4%BA%A4%E9%98%9F%E5%88%97%E3%80%81%E6%9C%89%E7%95%8C%E4%BB%BB%E5%8A%A1%E9%98%9F%E5%88%97%E3%80%81%E6%97%A0%E7%95%8C%E4%BB%BB%E5%8A%A1%E9%98%9F%E5%88%97%E3%80%81%E4%BC%98%E5%85%88%E4%BB%BB%E5%8A%A1%E9%98%9F%E5%88%97%E5%87%A0%E7%A7%8D%EF%BC%9B%0AthreadFactory%3A%E7%BA%BF%E7%A8%8B%E5%B7%A5%E5%8E%82%EF%BC%8C%E7%94%A8%E4%BA%8E%E5%88%9B%E5%BB%BA%E7%BA%BF%E7%A8%8B%EF%BC%8C%E4%B8%80%E8%88%AC%E7%94%A8%E9%BB%98%E8%AE%A4%E5%8D%B3%E5%8F%AF%EF%BC%9B%0Ahandler%3A%E6%8B%92%E7%BB%9D%E7%AD%96%E7%95%A5%EF%BC%9B%E5%BD%93%E4%BB%BB%E5%8A%A1%E5%A4%AA%E5%A4%9A%E6%9D%A5%E4%B8%8D%E5%8F%8A%E5%A4%84%E7%90%86%E6%97%B6%EF%BC%8C%E5%A6%82%E4%BD%95%E6%8B%92%E7%BB%9D%E4%BB%BB%E5%8A%A1%EF%BC%9B%0A%0A%E5%A4%9A%E7%BA%BF%E7%A8%8B%E8%AE%B2%E5%88%B0%E8%BF%99%E9%87%8C%EF%BC%8C%E6%88%91%E4%BB%AC%E5%BC%80%E5%A7%8B%E7%BB%A7%E7%BB%ADserver%E5%8A%A0%E5%85%A5%E7%BA%BF%E7%A8%8B%E6%B1%A0%E7%9A%84%E5%A4%84%E7%90%86%E3%80%82%0A%0A%23%23%23%20%E6%AF%8F%E4%B8%AA%E5%AE%A2%E6%88%B7%E7%AB%AF%E8%BF%9B%E8%A1%8C%E5%8D%95%E7%8B%AC%E5%A4%84%E7%90%86%0A%E9%A6%96%E5%85%88%EF%BC%8C%E6%88%91%E4%BB%AC%E9%9C%80%E8%A6%81%E5%A4%9A%E7%BA%BF%E7%A8%8B%E5%A4%84%E7%90%86%EF%BC%8C%E5%88%9B%E5%BB%BA%E7%BA%BF%E7%A8%8B%E6%B1%A0%0A%60%60%60%0AThreadPoolExecutor%20pool%C2%A0%20%3D%20new%20ThreadPoolExecutor(0%2C%20MaxClient%2C%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20%0A%20%20%20%20%20%20%20%20%20%20%20%2060L%2C%20TimeUnit.SECONDS%2C%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20%0A%20%20%20%20%20%20%20%20%20%20%20%20new%20SynchronousQueue%3CRunnable%3E())%3B%0A%60%60%60%0A%E5%85%B6%E4%B8%AD%EF%BC%8CMaxClient%E8%A1%A8%E7%A4%BA%E6%88%91%E4%BB%AC%E5%8F%AF%E4%BB%A5%E6%9C%80%E5%A4%9A%E6%8E%A5%E6%94%B6%E7%9A%84%E5%AE%A2%E6%88%B7%E7%AB%AF%E3%80%82%0Aserver%E7%9A%84%E6%96%B9%E6%B3%95%E5%A6%82%E4%B8%8B%EF%BC%9A%0A%60%60%60%0Atry%20(ServerSocket%20serverSocket%20%3D%20new%20ServerSocket(PORT))%20%7B%C2%A0%C2%A0%C2%A0%20%20%0A%20%20%20%20while%20(true)%20%7B%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20%0A%20%20%20%20%20%20%20%20task%20%3D%20serverSocket.accept()%3B%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20%0A%20%20%20%20%20%20%20%20try%20%7B%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%0A%20%20%20%20%20%20%20%20%20%20%20%20pool.execute(new%20ServerTask(task))%3B%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%0A%20%20%20%20%20%20%20%20%7D%20catch%20(RejectedExecutionException%20e)%20%7B%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(task%20!%3D%20null)%20%7B%C2%A0%C2%A0%20task.close()%3B%C2%A0%7D%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20%0A%20%20%20%20%20%20%20%20%7D%C2%A0%C2%A0%C2%A0%20%0A%20%20%20%20%7D%0A%7D%0A%60%60%60%0Aserver%E4%B8%AD%EF%BC%8Caccept%E4%BC%9A%E4%B8%8D%E6%96%AD%E7%AD%89%E5%BE%85%E6%96%B0%E7%9A%84%E5%AE%A2%E6%88%B7%E7%AB%AF%EF%BC%8C%E5%A6%82%E6%9E%9C%E6%9C%89%E6%96%B0%E7%9A%84%E5%AE%A2%E6%88%B7%E7%AB%AF%E8%BF%9B%E6%9D%A5%EF%BC%8C%E5%B0%B1%E6%8F%90%E4%BA%A4%E5%88%B0%E7%BA%BF%E7%A8%8B%E6%B1%A0%E8%BF%9B%E8%A1%8C%E9%80%9A%E4%BF%A1%E3%80%82ServerTask%20%E5%B0%B1%E6%98%AF%E5%AE%9A%E4%B9%89%E5%AF%B9%E5%BA%94%E7%9A%84%E9%80%9A%E4%BF%A1%E6%96%B9%E5%BC%8F%EF%BC%8C%E9%98%BB%E5%A1%9E%E8%AF%BB%E5%8F%96%E4%BF%A1%E6%81%AF%EF%BC%8C%E5%A6%82%E6%9E%9C%E6%9C%89%E6%B6%88%E6%81%AF%E8%BF%87%E6%9D%A5%EF%BC%8C%E5%B0%B1%E6%8A%8A%E6%94%B6%E5%88%B0%E7%9A%84%E6%B6%88%E6%81%AF%E5%8F%91%E9%80%81%E5%9B%9E%E5%8E%BB%E3%80%82%E5%A6%82%E6%9E%9C%E5%AE%A2%E6%88%B7%E7%AB%AF%E5%A4%9A%E4%BA%8EMaxClient%EF%BC%8C%E5%B0%B1%E4%BC%9A%E6%8A%9B%E5%87%BARejectedExecutionException%EF%BC%8C%E5%AE%9A%E4%B9%89%E5%A6%82%E4%B8%8B%EF%BC%9A%0A%60%60%60%0Aclass%20ServerTask%20implements%20Runnable%20%7B%C2%A0%C2%A0%C2%A0%0A%20%20%20%20private%20Socket%20task%20%3D%20null%3B%C2%A0%C2%A0%C2%A0%20%0A%20%20%20%20public%20ServerTask(Socket%20task)%20%7B%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%0A%20%20%20%20%20%20%20%20this.task%20%3D%20task%3B%C2%A0%C2%A0%C2%A0%20%0A%20%20%20%20%7D%C2%A0%C2%A0%C2%A0%20%0A%20%20%20%20%40Override%C2%A0%C2%A0%C2%A0%0A%20%20%20%20public%20void%20run()%20%7B%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20%0A%20%20%20%20try%20(%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20%0A%20%20%20%20%20%20%20%20ObjectOutputStream%20output%20%3D%20new%20%0A%20%20%20%20%20%20%20%20ObjectOutputStream(task.getOutputStream())%3B%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%0A%20%20%20%20%20%20%20%20ObjectInputStream%20input%20%3D%20new%20%0A%20%20%20%20%20%20%20%20ObjectInputStream(task.getInputStream())%3B%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20)%20%7B%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20%0A%20%20%20%20%20%20%20%20%20%20%20%20while%20(true)%20%7B%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20String%20msg%20%3D%20input.readUTF()%3B%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20output.writeUTF(%22server%E5%B7%B2%E7%BB%8F%E6%8E%A5%E6%94%B6%E5%88%B0%3A%22%20%2B%20msg)%3B%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20output.flush()%3B%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20%0A%20%20%20%20%20%20%20%20%7D%20%0A%20%20%20%20catch%20(IOException%20e)%20%7B%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20%0A%20%20%20%20%20%20%20%20System.out.println(%22%E5%B7%B2%E7%BB%8F%E6%96%AD%E5%BC%80%E8%BF%9E%E6%8E%A5%22)%3B%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20%7D%C2%A0%C2%A0%C2%A0%20%0A%20%20%20%20%7D%0A%7D%0A%0A%60%60%60%0A%0A%0A%23%23%23%20%E5%AE%A2%E6%88%B7%E7%AB%AF%E8%BE%93%E5%85%A5%E5%8F%91%E9%80%81%0A%E5%AE%A2%E6%88%B7%E7%AB%AF%E8%BF%9B%E8%A1%8C%E8%BE%93%E5%85%A5%E5%90%8E%E5%8F%91%E9%80%81%E5%B9%B6%E6%8E%A5%E6%94%B6%E6%9C%8D%E5%8A%A1%E7%AB%AF%E5%8F%91%E9%80%81%E8%BF%87%E6%9D%A5%E7%9A%84%E6%B6%88%E6%81%AF%EF%BC%8C%E4%BB%A3%E7%A0%81%E5%AE%9E%E7%8E%B0%E5%A6%82%E4%B8%8B%0A%60%60%60%0Aoutput%20%3D%20new%20ObjectOutputStream(socket.getOutputStream())%3B%0Ainput%20%3D%20new%20ObjectInputStream(socket.getInputStream())%3B%0A%0AScanner%20scanner%20%3D%20new%20Scanner(System.in)%3B%0Awhile(true)%20%7B%C2%A0%C2%A0%C2%A0%20%0A%20%20%20%20String%20msg%20%3D%20scanner.nextLine()%3B%C2%A0%C2%A0%C2%A0%20%0A%20%20%20%20output.writeUTF(msg)%3B%C2%A0%C2%A0%C2%A0%20%0A%20%20%20%20output.flush()%3B%C2%A0%C2%A0%C2%A0%20%0A%20%20%20%20%2F%2FString%20re%20%3D%20input.readUTF()%3B%C2%A0%C2%A0%C2%A0%0A%7D%0A%60%60%60%0A%0A%0A%E5%85%B7%E4%BD%93%E4%BB%A3%E7%A0%81%E5%8F%AF%E4%BB%A5%E5%8F%82%E8%80%83github%E9%A1%B9%E7%9B%AE%EF%BC%8C%E5%9C%A8%E7%9B%AE%E5%BD%95%EF%BC%9Acom%2Fokayjam%2Fnet%2Fsocket%2Ftcp%E4%B8%8B%0Ahttps%3A%2F%2Fgithub.com%2Fweiguang%2FJamJavaUtil%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A%0A
欢迎关注我公众号:

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据