# Java Socket BIO
之前用python2.7做了Socket的快速模型和研发校验,目前工作进入到产品release 开发阶段,所以服务器这方面的技术选型我选择了java(文档duo比较完善,第三方包也很多)
### 这里看过了java的并发,就自己准备封装了一下java的Socket服务器
#### 需要了解的知识点
[网上扒取得知识点地址]: https://blog.csdn.net/a78270528/article/details/80318571
* TCP
Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能,用户数据报协议(UDP)是同一层内 另一个重要的传输协议。在因特网协议族(Internet protocol suite)中,TCP层是位于IP层之上,应用层之下的中间层。不同主机的应用层之间经常需要可靠的、像管道一样的连接,但是IP层不提供这样的流机制,而是提供不可靠的包交换。
应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,然后TCP把数据流分区成适当长度的报文段(通常受该计算机连接的网络的数据链路层的最大传输单元( MTU)的限制)。之后TCP把结果包传给IP层,由它来通过网络将包传送给接收端实体的TCP层。TCP为了保证不发生丢包,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的包发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据包就被假设为已丢失将会被进行重传。TCP用一个校验和函数来检验数据是否有错误;在发送和接收时都要计算校验和。
* JAVA Socket
所谓socket 通常也称作”套接字“,用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过”套接字”向网络发出请求或者应答网络请求。
以J2SDK-1.3为例,Socket和ServerSocket(TCP的服务)类库位于java.net包中。ServerSocket用于服务器端,Socket是建立网络连接时使用的。在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。不管是Socket还是ServerSocket它们的工作都是通过SocketImpl类及其子类完成的。
**注意:**其中getInputStream和getOutputStream方法均会产生一个IOException,它必须被捕获,因为它们返回的流对象,通常都会被另一个流对象使用。
### 封装的服务器代码
* 封装类
```java
package com.server;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.*;
public class SocketServer {
//private String host;
private int port;
//private Socket socket;
ServerSocket server;
private int byteLength = 1024;
public SocketServer(int port)
{
//this.host = host;
this.port = port;
}
public void Connect() throws IOException {
server = new ServerSocket(port);
}
public void Listener()
{
while (true)
{
try {
System.out.println("Start socket wait......");
Socket socket = server.accept();
InetAddress address = socket.getInetAddress();
System.out.println("Socket access to this server address:" + address.getHostAddress() + "_name:" + address.getHostName());
InputStream inputStream = socket.getInputStream();
byte[] bytes = new byte[byteLength];
int len = inputStream.read(bytes);
StringBuilder sb = new StringBuilder();
if(len > 0){
sb.append(new String(bytes,0,len));
}
System.out.println("get data from:" +sb);
inputStream.close();
socket.close();
}catch (Exception e)
{
System.out.println(e.toString());
e.printStackTrace();
}
}
}
public void SendMsg(String data)
{
}
public void Close() throws IOException
{
server.close();
}
}
```
* 主函数调用测试
```java
import com.server.SocketServer;
public class Main {
public static void main(String[] args) {
SocketServer server =new SocketServer(888);
try{
server.Connect();
server.Listener();
server.Close();
}catch (Exception e)
{
System.out.println(e.toString());
}finally {
return;
}
}
}
```
### 测试
开了一个SocketTool2(需要的自己网上下载),创建了多个客户端去连接服务器,因为上面的服务器是基于BIO的(阻塞式),所以多个客户端谁先连接谁先被监听,知道这个客户端发送消息后才会到下个客户端的监听