`
kingxss
  • 浏览: 972979 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Java Socket学习笔记(三)- TCP服务端线程池

阅读更多

一、服务端回传服务类:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

public class EchoProtocol implements Runnable {
    private static final int BUFSIZE = 32; // Size (in bytes) of I/O buffer
    private Socket clientSocket; // Socket connect to client
    private Logger logger; // Server logger

    public EchoProtocol(Socket clientSocket, Logger logger) {
        this.clientSocket = clientSocket;
        this.logger = logger;
    }

    public static void handleEchoClient(Socket clientSocket, Logger logger) {
        try {
            // Get the input and output I/O streams from socket
            InputStream in = clientSocket.getInputStream();
            OutputStream out = clientSocket.getOutputStream();

            int recvMsgSize; // Size of received message
            int totalBytesEchoed = 0; // Bytes received from client
            byte[] echoBuffer = new byte[BUFSIZE]; // Receive Buffer
            // Receive until client closes connection, indicated by -1
            while ((recvMsgSize = in.read(echoBuffer)) != -1) {
                out.write(echoBuffer, 0, recvMsgSize);
                totalBytesEchoed += recvMsgSize;
            }

            logger.info("Client " + clientSocket.getRemoteSocketAddress() + ", echoed " + totalBytesEchoed + " bytes.");
            
        } catch (IOException ex) {
            logger.log(Level.WARNING, "Exception in echo protocol", ex);
        } finally {
            try {
                clientSocket.close();
            } catch (IOException e) {
            }
        }
    }

    public void run() {
        handleEchoClient(this.clientSocket, this.logger);
    }
}

 

 

二、每个客户端请求都新启一个线程的Tcp服务端:

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Logger;

public class TCPEchoServerThread {

    public static void main(String[] args) throws IOException {
        // Create a server socket to accept client connection requests
        ServerSocket servSock = new ServerSocket(5500);

        Logger logger = Logger.getLogger("practical");

        // Run forever, accepting and spawning a thread for each connection
        while (true) {
            Socket clntSock = servSock.accept(); // Block waiting for connection
            // Spawn thread to handle new connection
            Thread thread = new Thread(new EchoProtocol(clntSock, logger));
            thread.start();
            logger.info("Created and started Thread " + thread.getName());
        }
        /* NOT REACHED */
    }
}

 

三、固定线程数的Tcp服务端:

 

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

public class TCPEchoServerPool {
    public static void main(String[] args) throws IOException {
        int threadPoolSize = 3; // Fixed ThreadPoolSize

        final ServerSocket servSock = new ServerSocket(5500);
        final Logger logger = Logger.getLogger("practical");

        // Spawn a fixed number of threads to service clients
        for (int i = 0; i < threadPoolSize; i++) {
            Thread thread = new Thread() {
                public void run() {
                    while (true) {
                        try {
                            Socket clntSock = servSock.accept(); // Wait for a connection
                            EchoProtocol.handleEchoClient(clntSock, logger); // Handle it
                        } catch (IOException ex) {
                            logger.log(Level.WARNING, "Client accept failed", ex);
                        }
                    }
                }
            };
            thread.start();
            logger.info("Created and started Thread = " + thread.getName());
        }
    }
}

 

 

四、使用线程池(使用Spring的线程次会有队列、最大线程数、最小线程数和超时时间的概念),

1.线程池工具类:

import java.util.concurrent.*;

/**
 * 任务执行者
 * 
 * @author Watson Xu
 * @since 1.0.0 <p>2013-6-8 上午10:33:09</p>
 */
public class ThreadPoolTaskExecutor {

    private ThreadPoolTaskExecutor() {

    }

    private static ExecutorService executor = Executors.newCachedThreadPool(new ThreadFactory() {
        int count;

        /* 执行器会在需要自行任务而线程池中没有线程的时候来调用该程序。对于callable类型的调用通过封装以后转化为runnable */
        public Thread newThread(Runnable r) {
            count++;
            Thread invokeThread = new Thread(r);
            invokeThread.setName("Courser Thread-" + count);
            invokeThread.setDaemon(false);// //????????????

            return invokeThread;
        }
    });

    public static void invoke(Runnable task, TimeUnit unit, long timeout) throws TimeoutException, RuntimeException {
        invoke(task, null, unit, timeout);
    }

    public static <T> T invoke(Runnable task, T result, TimeUnit unit, long timeout) throws TimeoutException,
            RuntimeException {
        Future<T> future = executor.submit(task, result);
        T t = null;
        try {
            t = future.get(timeout, unit);
        } catch (TimeoutException e) {
            throw new TimeoutException("Thread invoke timeout ...");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return t;
    }

    public static <T> T invoke(Callable<T> task, TimeUnit unit, long timeout) throws TimeoutException, RuntimeException {
        // 这里将任务提交给执行器,任务已经启动,这里是异步的。
        Future<T> future = executor.submit(task);
        // System.out.println("Task aready in thread");
        T t = null;
        try {
            /*
             * 这里的操作是确认任务是否已经完成,有了这个操作以后 
             * 1)对invoke()的调用线程变成了等待任务完成状态
             * 2)主线程可以接收子线程的处理结果
             */
            t = future.get(timeout, unit);
        } catch (TimeoutException e) {
            throw new TimeoutException("Thread invoke timeout ...");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        return t;
    }
}

 

2.具有伸缩性的Tcp服务端:

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;

import demo.callable.ThreadPoolTaskExecutor;


public class TCPEchoServerExecutor {

    public static void main(String[] args) throws IOException {
        // Create a server socket to accept client connection requests
        ServerSocket servSock = new ServerSocket(5500);

        Logger logger = Logger.getLogger("practical");
        
        // Run forever, accepting and spawning threads to service each connection
        while (true) {
            Socket clntSock = servSock.accept(); // Block waiting for connection
            //executorService.submit(new EchoProtocol(clntSock, logger));
            try {
                ThreadPoolTaskExecutor.invoke(new EchoProtocol(clntSock, logger), TimeUnit.SECONDS, 3);
            } catch (Exception e) {
            } 
            //service.execute(new TimelimitEchoProtocol(clntSock, logger));
        }
        /* NOT REACHED */
    }
}

 

 参考:

1.《Java TCP/IP Socket编程(原书第2版)》

分享到:
评论

相关推荐

    【Socket编程】--TCP异步通讯一服务器多客户端

    在TCP异步通讯中,服务器并不直接等待每一个客户端的响应,而是采用非阻塞的方式处理多个客户端请求,这样可以提高服务端的并发处理能力,优化系统资源的利用。 首先,让我们来了解TCP服务器的基本构建。一个TCP...

    JAVA学习笔记4

    标题“JAVA学习笔记4”和描述“JAVA语言学习路上的笔记4,通过实际结合总结,使用Eclipse编辑代码”所涉及的知识点是Java语言的学习和实践,尤其是涉及到Java网络程序设计。这部分内容中提及了TCP网络编程以及相关的...

    JAVA学习笔记 林信良

    网络编程也是Java的一大亮点,书中介绍了Socket编程,让读者能够创建基于TCP/IP协议的客户端和服务端应用。此外,还涉及了Java的I/O和NIO(非阻塞I/O)框架,这些都是进行文件操作和网络通信的基础。 最后,书中还...

    MLDN 2009 JAVA SE 笔记16-23

    8. **网络编程**:Java提供了Socket和ServerSocket类来进行TCP/IP通信,笔记可能会讲解如何创建客户端和服务端,进行数据的收发。 9. **JNI(Java Native Interface)**:如果笔记深入,可能会触及JNI,它是Java与...

    Java-J2SE学习笔记

    - **Socket编程**:创建TCP连接,进行客户端和服务端的数据交换。 - **URL与URLConnection**:处理HTTP请求,获取网页内容。 8. **反射机制**: - **Class类**:获取类的信息,动态创建和调用对象。 - **Method...

    Java随堂笔记

    - **Socket编程**:客户端与服务器端的通信,TCP和UDP协议。 - **HTTP协议**:理解HTTP请求和响应的结构,实现简单的HTTP客户端和服务端。 8. **Java虚拟机(JVM)** - **内存管理**:堆、栈、方法区、本地方法...

    java笔记 java笔记 java笔记

    - **Socket编程**:基于TCP协议的网络通信,ServerSocket和Socket类用于客户端和服务端交互。 - **HTTP协议**:Java的HttpURLConnection类用于发送HTTP请求和接收响应。 8. **反射与注解(Annotations)**: - **...

    java学习笔记之大鹏JAVA终级总结

    Java学习笔记之大鹏JAVA终级总结,是针对Java编程语言深入学习和面试准备的一份综合资料。这份总结涵盖了从基础知识到高级概念的多个方面,旨在帮助初学者理解和掌握Java的核心概念,同时解决面试中可能出现的关键...

    java学习笔记

    网络编程也是Java的一大亮点,Java学习笔记会介绍Socket编程,使读者能够创建基于TCP/IP的客户端和服务端应用程序。此外,还会涉及多线程编程,这是并发处理和提高程序性能的关键技术,包括线程的创建、同步和通信。...

    java从0基础学习笔记

    本学习笔记将全面涵盖这些内容,帮助你构建坚实的Java编程基础。 1. **Java基本语法** - 变量:了解数据类型,如整型、浮点型、字符型、布尔型等,并学会声明和初始化变量。 - 运算符:掌握算术、比较、逻辑、位...

    Java 基础 第3阶段:高级应用-尚硅谷学习笔记(含面试题) 2023年

    在这个阶段的学习中,尚硅谷提供了2023年的学习笔记和面试题,帮助你提升Java技能并为求职做好准备。 首先,多线程是Java的一个关键特性,允许程序同时执行多个任务。理解线程的创建(通过Thread类或实现Runnable...

    java基础知识学习笔记

    在网络编程方面,Java提供Socket编程接口,可以创建客户端和服务端进行通信。你会学习如何创建TCP和UDP套接字,实现数据的发送和接收。 多线程是Java的另一个强项。Java内置了对多线程的支持,通过Thread类和...

    Socket网络编程学习笔记

    ### Socket网络编程学习笔记 #### 一、基础知识与常用类介绍 ##### 1. IP地址操作类 在开始深入探讨Socket编程之前,我们首先要了解一些基础的类和方法,这将帮助我们在实际开发中更加高效地解决问题。 **1.1 IP...

    java学习笔记基础和框架

    1. **Socket编程**:学习TCP和UDP协议,编写客户端和服务端程序,实现数据的发送和接收。 2. **HTTP协议**:理解HTTP的工作原理,创建基于HTTP的Java客户端和服务器。 3. **Web服务**:包括RESTful API的设计和实现...

    java学习资料 学习笔记

    根据提供的文件信息,标题为“java学习资料 学习笔记”,描述部分虽然重复了“学习资料”这个词,但我们可以理解这份材料是关于Java编程语言的学习资料。由于描述和标签部分的信息较为有限,我们将依据这些关键词...

    JAVA试题 JAVA复习题 JAVA复习笔记

    - **Socket编程**:客户端与服务端的交互,TCP与UDP的区别。 - **HTTP协议**:理解HTTP请求和响应的结构。 8. **JDBC数据库操作** - **连接数据库**:使用DriverManager获取数据库连接。 - **执行SQL语句**:...

    Javaq备战秋招面试题-重点学习笔记.zip

    这份"Javaq备战秋招面试题-重点学习笔记.zip"文件包含了面试必备的Java知识点,帮助你全面复习并提升技能。 1. **基础语法**:理解并掌握Java的基础语法是所有Java程序员的起点,包括变量、数据类型(基本类型和...

    在工作中java学习资料学习笔记

    6. **网络编程**:Java提供Socket编程接口,可以用于创建客户端和服务端应用程序。理解TCP和UDP协议,以及如何使用Java实现网络通信。 7. **异常处理**:Java的异常处理机制通过try-catch-finally语句块来捕获和...

    socket网络编程学习笔记

    本笔记主要探讨了IP地址操作、DNS解析以及如何在服务端建立Socket监听。 首先,IP地址操作涉及到`IPAddress`和`IPEndPoint`两个类。`IPAddress`类提供了对IP地址的处理能力,如`Parse()`方法可以将点分十进制的IP...

Global site tag (gtag.js) - Google Analytics