客户端Socket与服务端ServerSocket串联实现网络通信

目录
  • 引导语
  • 1、类属性
  • 2、初始化
  • 3、bind
  • 4、accept
  • 5、面试题
    • 5.1、说说你对Socket和ServerSocket的理解?
    • 5.2、说说对SocketOptions中的SO_TIMEOUT的理解?
    • 5.3、在构造Socket的时候,我可以选择TCP或UDP么?应该如何选择?
    • 5.4、TCP有自动检测服务端是否存活的机制么?有没有更好的办法?
  • 总结

引导语

上一小节我们学习了 Socket,本文我们来看看服务端套接字 API:ServerSocket,本文学习完毕之后,我们就可以把客户端 Socket 和服务端 ServerSocket 串联起来,做一个真实的网络通信的 demo 了。

1、类属性

ServerSocket 的主要作用,是作为服务端的套接字,接受客户端套接字传递过来的信息,并把响应回传给客户端,其属性非常简单,如下:

private boolean created = false;// 已创建
private boolean bound = false;// 绑定
private boolean closed = false;// 已关闭
// 底层的功能都依靠 SocketImpl 来实现
private SocketImpl impl;

ServerSocket 和 Socket 一样,底层都是依靠 SocketImpl 的能力,而 SocketImpl 底层能力的实现基本上都是 native 方法实现的。

2、初始化

初始化大概可以分成两类:无参构造器和有参构造器。

无参构造器做的事情比较简单,只指定了 SocketImpl 为 SocksSocketImpl 类;有参构造器有几种初始化的形式,我们一起来看一下参数最多的构造器的源码。

public ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException {
    // 默认是 SocksSocketImpl 实现
    setImpl();
    // 端口必须大于 0,小于 65535
    if (port < 0 || port > 0xFFFF)
        throw new IllegalArgumentException(
                   "Port value out of range: " + port);
    // 最大可连接数如果小于1,那么采取默认的 50
    if (backlog < 1)
      backlog = 50;
    try {
        // 底层 navtive 方法
        bind(new InetSocketAddress(bindAddr, port), backlog);
    } catch(SecurityException e) {
        close();
        throw e;
    } catch(IOException e) {
        close();
        throw e;
    }
}

入参 port 指的是 ServerSocket 需要绑定本地那个端口。

入参 backlog 指的是服务端接受客户端连接队列的最大长度,这里需要注意的是,这里并不是限制客户端连接的个数,我们在 JDK8 版本下做过实验,我们把服务端的 backlog 设置成 1,并且变慢服务端的处理速度,当服务端并发请求过来时,并不是第二个请求过来就拒绝连接,我们在实际工作中,最好也不要用 backlog 来限制客户端连接的个数。

还有点需要注意的是 backlog 小于 1 时,backlog 会被设置成默认的 50。

入参 InetAddress 表示 ip 地址。

3、bind

bind 方法主要作用是把 ServerSocket 绑定到本地的端口上,只有当我们使用无参构造器初始化 ServerSocket 时,才会用到这个方法,如果使用有参构造器的话,在初始化时就已经绑定到本地的端口上了。

配合无参构造器,一般我们这么用:

// 进行初始化
ServerSocket serverSocket = new ServerSocket();
// 进行绑定
serverSocket.bind(new InetSocketAddress("localhost", 7007));

4、accept

accept 方法主要是用来 ServerSocket 接受来自客户端的套接字的,如果此时没有来自客户端的请求时,该方法就会一直阻塞,如果有通过 setSoTimeout 方法设置超时时间,那么 accept 只会在超时间内阻塞,过了超时时间就会抛出异常。

bind 和 accept 方法底层都是 native 方法实现,我们就不看源码了。

5、面试题

5.1、说说你对 Socket 和 ServerSocket 的理解?

答:两者我们都可以称为套接字,底层基于 TCP/UDP 协议,套接字对底层协议进行了封装,让我们使用时更加方便,Socket 常被使用在客户端,用于向服务端请求数据和接受响应,ServerSocket 常用于在服务端,用于接受客户端的请求并进行处理,两者其底层使用都是依靠 SocketImpl 的子类的 native 方法。

5.2、说说对 SocketOptions 中的 SO_TIMEOUT 的理解?

答:SocketOptions 类有很多属性设置,比如 SO_TIMEOUT 、SO_LINGER 等等,这些问题说一下自己的理解即可,可以参考 《Socket 源码及面试题》 中对各种属性的解析。

5.3、在构造 Socket 的时候,我可以选择 TCP 或 UDP 么?应该如何选择?

答:可以的,Socket 有三个参数的构造器,第三个参数表示你想使用 TCP 还是 UDP。

5.4、TCP 有自动检测服务端是否存活的机制么?有没有更好的办法?

答:有的,我们可以通过 setKeepAlive 方法来激活该功能,如果两小时内,客户端和服务端的套接字之间没有任何通信,TCP 会自动发送 keepalive 探测给服务端,预测服务端有三种情况:

  • 服务端使用预期的 ACK 回复,说明一切正常;
  • 服务端回复 RST,表示服务端处于死机或者重启状态,终止连接;
  • 没有得到服务端的响应(会尝试多次),表示套接字已经关闭了。

但我们并不建议使用这种方式,我们可以自己起一个定时任务,定时的访问服务端的特殊接口,如果服务端返回的数据和预期一致,说明服务端是存活的。

总结

Socket 和 ServerSocket 在源码方面没啥特别可说的地方,基本都是一些设置,底层实现都是 native 的方法,但面试官会从此延伸到一些网络协议方面的知识,因为这已经超出本专栏的范畴了,感兴趣的同学可以自行百度。

以上就是客户端Socket与服务端ServerSocket串联实现网络通信的详细内容,更多关于Socket与ServerSocket串联实现网络通信的资料请关注我们其它相关文章!

(0)

相关推荐

  • Java基于socket实现的客户端和服务端通信功能完整实例

    本文实例讲述了Java基于socket实现的客户端和服务端通信功能.分享给大家供大家参考,具体如下: 以下代码参考马士兵的聊天项目,先运行ChatServer.java实现端口监听,然后再运行ChatClient.java 客户端实例 ChatClient.java package socketDemo; import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; public class Ch

  • 基于Java的Socket多客户端Client-Server聊天程序的实现

    任务要求 编写一个简单的Socket多客户端聊天程序: 客户端程序,从控制台输入字符串,发送到服务器端,并将服务器返回的信息显示出来 服务器端程序,从客户机接收数据并打印,同时将从标准输入获取的信息发送给客户机 满足一个服务器可以服务多个客户 低配版本链接 实现代码 工具类 import java.io.DataOutputStream; import java.io.IOException; import java.io.OutputStream; import java.net.Socket

  • 详解基于java的Socket聊天程序——服务端(附demo)

    写在前面: 昨天在博客记录自己抽空写的一个Socket聊天程序的初始设计,那是这个程序的整体设计,为了完整性,今天把服务端的设计细化记录一下,首页贴出Socket聊天程序的服务端大体设计图,如下图: 功能说明: 服务端主要有两个操作,一是阻塞接收客户端的socket并做响应处理,二是检测客户端的心跳,如果客户端一段时间内没有发送心跳则移除该客户端,由Server创建ServerSocket,然后启动两个线程池去处理这两件事(newFixedThreadPool,newScheduledThrea

  • 使用socket进行服务端与客户端传文件的方法

    逻辑: 1.客户端将需要查找的文件名以流的形式传给服务端 2.服务端接受客户端的连接,把流转化为字符串,进行一个目录的遍历,查找是否存在需要的文件,若未找到,则输出未找到,若找到,则将文件转化为流,传给客户端 3.客户端准备接受,将服务端传过来的流转化为文件,存储下载. 4,至此,完成一个简单的客户端与服务端传输文件的小栗子~ Client.Java package com.ysk; import java.io.BufferedReader; import java.io.FileOutput

  • Java编程Socket实现多个客户端连接同一个服务端代码

    Java Socket(套接字)通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过"套接字"向网络发出请求或者应答网络请求. 使用Socket实现多个客户端和同一客户端通讯:首先客户端连接服务端发送一条消息,服务端接收到消息后进行处理,完成后再回复客户端一条消息.本人通过自己的思维编写了一份服务端和客户端实现的代码,望能与大家相互学习,共同进步. 服务端代码 /** * Socket服务端 * 功能说明: * */ public cl

  • 客户端Socket与服务端ServerSocket串联实现网络通信

    目录 引导语 1.类属性 2.初始化 3.bind 4.accept 5.面试题 5.1.说说你对Socket和ServerSocket的理解? 5.2.说说对SocketOptions中的SO_TIMEOUT的理解? 5.3.在构造Socket的时候,我可以选择TCP或UDP么?应该如何选择? 5.4.TCP有自动检测服务端是否存活的机制么?有没有更好的办法? 总结 引导语 上一小节我们学习了 Socket,本文我们来看看服务端套接字 API:ServerSocket,本文学习完毕之后,我们就

  • Java通过socket客户端保持连接服务端实现代码

    这篇文章主要介绍了Java通过socket客户端保持连接服务端实现代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 业务场景:现在有一个socket服务端给我们发送数据,我们需要建立一个socket Client来连接这个socket Server,然后接受server发送过来的数据.但是这个server可能会中断,所以在Client要有一个while死循环去时刻保持与Server的连接. package com.thinkgem.wlw.m

  • python网络编程socket实现服务端、客户端操作详解

    本文实例讲述了python网络编程socket实现服务端.客户端操作.分享给大家供大家参考,具体如下: 本文内容: socket介绍 TCP: 服务端 客户端 UDP: 服务端 客户端 首发时间:2018-02-08 01:14 修改: 2018-03-20 :重置了布局,增加了UDP 什么是socket: socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求. 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为

  • Ajax客户端异步调用服务端的实现方法(js调用cs文件)

    ajax的使用方法,在js中调用cs文件中的一直方式,使用步骤如下 (1)下载ajax.dll,并添加项目的引用. (2)在项目的webconfig的<httpHandlers>节点中,添加<add verb="POST,GET" path="ajax/*.ashx" type="Ajax.PageHandlerFactory, Ajax"/>节点 (3)在aspx页面的pageload方法中添加Ajax.Utility.

  • udp socket客户端和udp服务端程序示例分享

    Udp Socket 复制代码 代码如下: #include <WinSock2.h>#include <stdio.h>#pragma comment(lib, "ws2_32.lib")int main(){// initial socket libraryWORD wVerisonRequested;WSADATA wsaData;int err;wVerisonRequested = MAKEWORD(1, 1);err = WSAStartup(wVe

  • 简单的java socket客户端和服务端示例

    客户端 复制代码 代码如下: import java.io.BufferedReader;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.Socket; public class MyClient {      public static void main(String[] args) throws Exception {          Socket socket = new Socke

  • python Socket之客户端和服务端握手详解

    简单的学习下利用socket来建立客户端和服务端之间的连接并且发送数据 1. 客户端socketClient.py代码 import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 建立连接: s.connect(('127.0.0.1', 9999)) # 接收欢迎消息: print(s.recv(1024).decode('utf-8')) for data in [b'Michael', b'Tracy', b'

  • Socket结合线程池使用实现客户端和服务端通信demo

    目录 引导语 1.要求 2.客户端代码 3.服务端代码 3.1.对客户端请求进行控制 3.2.服务端任务的处理逻辑 4.测试 5.总结 引导语 Socket 面试最终题一般都是让你写一个简单的客户端和服务端通信的例子,本文就带大家一起来写这个 demo. 1.要求 可以使用 Socket 和 ServiceSocket 以及其它 API: 写一个客户端和服务端之间 TCP 通信的例子: 服务端处理任务需要异步处理: 因为服务端处理能力很弱,只能同时处理 5 个请求,当第六个请求到达服务器时,需要

随机推荐