Socket 编程详解

  • 套接字使用TCP提供了两台计算机之间的通信机制。 客户端程序创建一个套接字,并尝试连接服务器的套接字。当连接建立时,服务器会创建一个 Socket 对象。客户端和服务器现在可以通过对 Socket 对象的写入和读取来进行通信。java.net.Socket 类代表一个套接字,并且 java.net.ServerSocket 类为服务器程序提供了一种来监听客户端,并与他们建立连接的机制。以下步骤在两台计算机之间使用套接字建立TCP连接时会出现:
    • 服务器实例化一个 ServerSocket 对象,表示通过服务器上的端口通信。
    • 服务器调用 ServerSocket 类的 accept() 方法,该方法将一直等待,直到客户端连接到服务器上给定的端口。
    • 服务器正在等待时,一个客户端实例化一个 Socket 对象,指定服务器名称和端口号来请求连接。
    • Socket 类的构造函数试图将客户端连接到指定的服务器和端口号。如果通信被建立,则在客户端创建一个 Socket 对象能够与服务器进行通信。
    • 在服务器端,accept() 方法返回服务器上一个新的 socket 引用,该 socket 连接到客户端的 socket。
    • 连接建立后,通过使用 I/O 流在进行通信,每一个socket都有一个输出流和一个输入流,客户端的输出流连接到服务器端的输入流,而客户端的输入流连接到服务器端的输出流。
  • TCP 是一个双向的通信协议,因此数据可以通过两个数据流在同一时间发送.以下是一些类提供的一套完整的有用的方法来实现 socket。

    • Socket通信的步骤① 创建ServerSocket和Socket② 打开连接到Socket的输入/输出流③ 按照协议对Socket进行读/写操作④ 关闭输入输出流、关闭Socket
      • 服务器端:

        • ① 创建ServerSocket对象,绑定监听端口
        • ② 通过accept()方法监听客户端请求
        • ③ 连接建立后,通过输入流读取客户端发送的请求信息
        • ④ 通过输出流向客户端发送信息
        • ⑤ 关闭相关资源
      • 客户端:

        • ① 创建Socket对象,指明需要连接的服务器的地址和端口号
        • ② 连接建立后,通过输出流想服务器端发送请求信息
        • ③ 通过输入流获取服务器响应的信息
        • ④ 关闭响应资源
  • BIO:
    • 服务器端实际有2个socket:一个用于监听,一个用于传输
      • 2个堵塞
        • 在等待连接accpet时候
        • 在等待客户端传输数据read的时候
    • 客户端只有一个用于传输
    • 这样的通信模式单线程通信无法处理并发(要开线程处理并发,浪费线程资源cpu),因为2次堵塞,当一个客户端和服务器端连接成功之后,如果它不发送任何数据信息,那么服务器端就会一直堵塞等待它发送信息,那么其他的客户端根本无法连接这个服务器。如果有创建的多个线程是不活跃的,只是连接不传递信息,考虑用单线程实现;
  • NIO:
    • 如果将read设置为非阻塞:c1进来连接服务器(将其设置为非阻塞),但没法发送信息,从新将服务器设置为等待连接,此时c2连接(也是设置成非阻塞),但此时c1要发送信息了,可能服务器状态在accept那里阻塞了,直接放弃了cpu使用,所以它无法发送信息的,此时就需要将accept也设置成非组赛;

    • 此时将accept和read都进行非阻塞设置:SocketChannel和SeverSocketChannel,用ByteBuffer.allocate(BLOCK);  设置缓存空间,再由SocketChannel读取;
      • 此处可以将每一个连接的SocketChannel,放进一个list做轮询,有数据就拿出数据读取,但造成了资源浪费,如何让java去主动感知有数据的socket?轮询将给了操作系统的函数
      • epoll函数(Unix)当有数据来了,它回直接告诉你是那个socket,不用去做轮询
      • serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);  将我们的socket注册给操作系统(在window在就是用select做轮询,在Linux在就是epoll函数)
      • redis只有Linux下,只用采用epoll(牛逼)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值