`

[Java]Socket和ServerSocket学习笔记

阅读更多

对于即时类应用或者即时类的游戏,HTTP协议很多时候无法满足于我们的需求。这会,Socket对于我们来说就非常实用了。下面是本次学习的笔记。主要分异常类型、交互原理、Socket、ServerSocket、多线程这几个方面阐述。

 

异常类型
在了解Socket的内容之前,先要了解一下涉及到的一些异常类型。以下四种类型都是继承于IOException,所以很多之后直接弹出IOException即可。
UnkownHostException:      主机名字或IP错误
ConnectException:        服务器拒绝连接、服务器没有启动、(超出队列数,拒绝连接)
SocketTimeoutException:      连接超时
BindException:          Socket对象无法与制定的本地IP地址或端口绑定
 
交互过程
Socket与ServerSocket的交互,下面的图片我觉得已经说的很详细很清楚了。
 
Socket
构造函数

Socket()

Socket(InetAddress address, int port)throws UnknownHostException, IOException
Socket(InetAddress address, int port, InetAddress localAddress, int localPort)throws IOException
Socket(String host, int port)throws UnknownHostException, IOException
Socket(String host, int port, InetAddress localAddress, int localPort)throws IOException
 
除去第一种不带参数的之外,其它构造函数会尝试建立与服务器的连接。如果失败会抛出IOException错误。如果成功,则返回Socket对象。
InetAddress是一个用于记录主机的类,其静态getHostByName(String msg)可以返回一个实例,其静态方法getLocalHost()也可以获得当前主机的IP地址,并返回一个实例。Socket(String host, int port, InetAddress localAddress, int localPort)构造函数的参数分别为目标IP、目标端口、绑定本地IP、绑定本地端口。
 
Socket方法
getInetAddress();      远程服务端的IP地址
getPort();          远程服务端的端口
getLocalAddress()      本地客户端的IP地址
getLocalPort()        本地客户端的端口
getInputStream();     获得输入流
getOutStream();      获得输出流
值得注意的是,在这些方法里面,最重要的就是getInputStream()和getOutputStream()了。
 
Socket状态
isClosed();            //连接是否已关闭,若关闭,返回true;否则返回false
isConnect();      //如果曾经连接过,返回true;否则返回false
isBound();            //如果Socket已经与本地一个端口绑定,返回true;否则返回false
如果要确认Socket的状态是否处于连接中,下面语句是很好的判断方式。
boolean isConnection=socket.isConnected() && !socket.isClosed();   //判断当前是否处于连接

 半关闭Socket

很多时候,我们并不知道在获得的输入流里面到底读多长才结束。下面是一些比较普遍的方法:
  • 自定义标识符(譬如下面的例子,当受到“bye”字符串的时候,关闭Socket)
  • 告知读取长度(有些自定义协议的,固定前几个字节表示读取的长度的)
  • 读完所有数据
  • 当Socket调用close的时候关闭的时候,关闭其输入输出流

ServerSocket

构造函数
ServerSocket()throws IOException
ServerSocket(int port)throws IOException
ServerSocket(int port, int backlog)throws IOException
ServerSocket(int port, int backlog, InetAddress bindAddr)throws IOException
 
注意点:
1. port服务端要监听的端口;backlog客户端连接请求的队列长度;bindAddr服务端绑定IP
2. 如果端口被占用或者没有权限使用某些端口会抛出BindException错误。譬如1~1023的端口需要管理员才拥有权限绑定。
3. 如果设置端口为0,则系统会自动为其分配一个端口;
4. bindAddr用于绑定服务器IP,为什么会有这样的设置呢,譬如有些机器有多个网卡。
5. ServerSocket一旦绑定了监听端口,就无法更改。ServerSocket()可以实现在绑定端口前设置其他的参数。
 
单线程的ServerSocket例子
public void service(){
    while(true){
        Socket socket=null;
        try{
            socket=serverSocket.accept();//从连接队列中取出一个连接,如果没有则等待
            System.out.println("新增连接:"+socket.getInetAddress()+":"+socket.getPort());
            ...//接收和发送数据
        }catch(IOException e){e.printStackTrace();}finally{
            try{
                if(socket!=null) socket.close();//与一个客户端通信结束后,要关闭Socket
            }catch(IOException e){e.printStackTrace();}
        }
    }
}
 

 

多线程的ServerSocket
多线程的好处不用多说,而且大多数的场景都是多线程的,无论是我们的即时类游戏还是IM,多线程的需求都是必须的。下面说说实现方式:
  • 主线程会循环执行ServerSocket.accept();
  • 当拿到客户端连接请求的时候,就会将Socket对象传递给多线程,让多线程去执行具体的操作;
实现多线程的方法要么继承Thread类,要么实现Runnable接口。当然也可以使用线程池,但实现的本质都是差不多的。
 
这里举例:
下面代码为服务器的主线程。为每个客户分配一个工作线程:
public void service(){
    while(true){
        Socket socket=null;
        try{
            socket=serverSocket.accept();                        //主线程获取客户端连接
            Thread workThread=new Thread(new Handler(socket));    //创建线程
            workThread.start();                                    //启动线程
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

 

当然这里的重点在于如何实现Handler这个类。Handler需要实现Runnable接口:
class Handler implements Runnable{
    private Socket socket;
    public Handler(Socket socket){
        this.socket=socket;
    }
    
    public void run(){
        try{
            System.out.println("新连接:"+socket.getInetAddress()+":"+socket.getPort());
            Thread.sleep(10000);
        }catch(Exception e){e.printStackTrace();}finally{
            try{
                System.out.println("关闭连接:"+socket.getInetAddress()+":"+socket.getPort());
                if(socket!=null)socket.close();
            }catch(IOException e){
                e.printStackTrace();
            }
        }
    }
}

当然是先多线程还有其它的方式,譬如线程池,或者JVM自带的线程池都可以。这里就不说明了。

分享到:
评论

相关推荐

    [Java]详解Socket和ServerSocket学习笔记

    Socket和ServerSocket是Java中实现网络通信的核心组件,它们提供了基于TCP/IP协议的低级通信接口。在HTTP协议无法满足实时性要求的应用场景,如即时通讯、在线游戏等,Socket成为了首选。本篇将深入讲解Socket和...

    Java 学习笔记Java学习笔记

    Java是一种广泛使用的面向对象的编程语言,由Sun Microsystems(现为Oracle公司的一部分)于1995年发布。...Java学习笔记涵盖了这些核心知识点,通过深入学习和实践,你可以逐步掌握Java编程,并应用于实际项目开发中。

    学习笔记:多线程Java Socket编程示例

    总结来说,这个学习笔记提供了一个使用Java Socket编程实现多线程服务器的示例,它演示了如何利用ExecutorService创建线程池来处理并发连接,是理解Java并发编程和网络通信的一个实用案例。虽然这是一个学习笔记,但...

    Java基础尚硅谷宋红康学习笔记

    5. **输入/输出**:Java的I/O流系统支持文件操作和网络通信,如FileReader、FileWriter、BufferedReader、BufferedWriter以及Socket、ServerSocket等类。 6. **字符串处理**:String类在Java中扮演重要角色,提供了...

    java学习笔记-Scokect.pdf

    Java学习笔记-Scoket.pdf ...Java学习笔记-Scoket.pdf涵盖了Socket编程的基础知识、Java中Socket的使用、Socket通信的原理及应用等方面的内容,为学习Java编程语言和Socket编程提供了系统的参考资料。

    Socket网络编程学习笔记

    在本学习笔记中,我们将深入探讨Socket编程的基本概念、原理以及如何在实际项目中应用。 首先,Socket是网络通信的接口,它提供了一种标准的方式让应用程序能够发送和接收数据。在TCP/IP协议栈中,Socket扮演着...

    Java公司培训经典学习笔记

    这份Java公司培训经典学习笔记全面覆盖了Java开发的核心知识点,对于初学者来说是一份很好的启蒙材料,对于有经验的开发者则能作为巩固和拓展知识的参考。通过深入学习和实践,可以有效提升Java编程能力,为参与复杂...

    JAVA 自己的学习笔记总结

    ### JAVA学习笔记:Socket通信详解 #### 一、Socket通信概念与原理 Socket通信是Java网络编程中的核心概念,它提供了在不同计算机之间进行数据交换的能力。Socket可以被视为两个程序间进行通信的端点,一个Socket...

    Java+JDK6学习笔记

    8. **网络编程**:学习Java的Socket编程,包括TCP和UDP通信,以及ServerSocket和Socket类的使用。 9. **Swing GUI**:JDK6对Swing组件进行了优化,可以创建丰富的图形用户界面。学习JFrame、JButton、JLabel、...

    Java学习笔记(必看经典).doc

    6. **输入/输出流**:Java提供了强大的I/O流系统,支持文件读写、网络通信和数据序列化等操作,如FileInputStream和FileOutputStream用于文件操作,Socket和ServerSocket用于网络编程。 7. **多线程**:Java内置了...

    Java语言程序设计学习笔记

    Java语言程序设计学习笔记是为初学者和有一定基础的开发者准备的一份详尽教程,它涵盖了从基础到进阶的各个重要知识点。这份笔记以Markdown(md)文件的形式组织,便于阅读和检索,使得学习过程更为高效。 首先,...

    Java 客户端服务器程序 学习笔记

    在这个“Java客户端服务器程序学习笔记”中,我们将深入探讨这一主题,包括如何设计、实现和交互这两个关键组件。 首先,客户端是用户与系统进行交互的部分,它发送请求到服务器并接收响应。服务器端则处理这些请求...

    Java学习笔记(整理)

    11. **网络编程**:Java的Socket和ServerSocket类可用于网络通信,实现客户端-服务器模式的应用。 12. **反射机制**:反射允许在运行时检查类的信息,创建和调用对象,是Java动态性的重要体现。 13. **泛型**:...

    j2se学习笔记和java学习笔记

    Java提供了Socket和ServerSocket类来进行网络编程,可以创建客户端和服务端进行通信,实现分布式应用。 九、反射与注解 反射是Java的一种动态类型能力,可以在运行时检查类、接口、字段和方法的信息。注解...

    良葛格JAVA 学习笔记

    在《JAVA 学习笔记》中,良葛格深入浅出地讲解了Java编程语言的基础知识和进阶技巧,旨在帮助读者从零开始掌握这一广泛应用于企业级开发的重要语言。以下是该学习笔记中可能涵盖的一些核心知识点: 1. **Java基础...

    良葛格Java学习笔记(完整版)

    总的来说,《良葛格Java学习笔记(完整版)》是一份覆盖广泛、深度适宜的Java学习资源,它将帮助你系统地理解和掌握这门强大的编程语言,无论你是正在踏入Java世界的新手,还是希望提升技术水平的开发者,都能从中找到...

    java面试题 学习笔记

    本篇将基于常见的Java面试问题,结合学习笔记,深入探讨Java的核心概念和技术。 一、Java基础 1. Java的特性:了解Java的“一次编写,到处运行”的平台无关性,以及它的面向对象特性,如封装、继承和多态。 2. 类与...

    JAVA学习笔记

    JAVA学习笔记是一个全面涵盖JAVA编程基础到进阶的资源集合,特别适合初学者掌握JAVA语言和项目开发技术。笔记内容包括了几个核心领域,如编程思想、多线程设计模式、网络编程,以及JAVA的新输入/输出(NIO)系统。 ...

    java从0基础学习笔记

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

    良葛格Java学习笔记

    以上内容是“良葛格Java学习笔记”中的核心知识点,通过深入学习和实践,可以帮助读者建立起坚实的Java基础,进一步提升编程技能。其中,ch01.pdf可能详细介绍了Java的基础知识,而ch02.pdf可能涵盖了更高级的主题,...

Global site tag (gtag.js) - Google Analytics