三、Socket简解

2022-03-25  本文已影响0人  小鱼你好

Socket是应用层与TCP/IP协议族通信的中间软件抽象层,他是一组接口,把复杂的TCP/IP协议族隐藏在Socket接口后面,用户使用Socket提供的接口即能实现连接远程机器-发送数据-接收数据-关闭连接-绑定端口-监听到达数据-在绑定的端口上接受来自远程机器的连接。Socket分为服务端ServerSocket和客户端Socket,建立连接时要分别创建对应的Socket实例。

客户端Socket构造方法说明:

Socket():创建一个新的未连接的Socket。
Socket(Proxy proxy):使用指定的代理类型创建一个新的未连接的Socket。
Socket(Sting dstName,int dstPort):使用指定的目标服务器IP地址和目标服务器端口号创建一个新的Socket。
Socket(Sting dstName,int dstPort,InetAddress localAddress,int localPort):使用指定的目标主机、目标端口、本地地址和本地端口,创建一个新的 Socket。
Socket(InetAddress localAddress,int localPort):使用指定的本地地址和本地端口,创建一个新的 Socket。
Socket(InetAddress dstAddress,int dstPort,InetAddress localAddress,int localPort):使用指定的目标主机、目标端口、本地地址和本地端口,创建一个新的 Socket。
其中,proxy为代理服务器地址,dstAddress为目标服务器IP地址,dstPort为目标服务器端口号,dstName为目标服务器主机名。

Socket client=new Socket("192.168.1.23", 2012); 
// 第一个参数是目标服务器的 IP 地址,2012 是目标服务器的端口号

客户端Socket重要方法说明:

public InputStream getInputStream():读出该Socket中的数据。
public OutputStream getOutputStream():向Socke中写入数据。
public synchronized void close():关闭该Socket。

服务端ServiceSocket构造方法说明:

ServiceSocket():构造一个新的未绑定的ServiceSocket。
ServiceSocket(int port):构造一个新的ServiceSocket实例并绑定到指定端口,如果port为0,端口将由操作系统自动分配,此时进入队列的数目将被设置为50。
ServiceSocket(int port,int backlog):构造一个新的ServiceSocket实例并绑定到指定端口,并且指定进入队列的数目,如果port为0端口号由系统分配。
ServiceSocket(int port,int backlog,InetAddress localAddress):构造一个新的ServiceSocket实例并绑定到指定端口和指定地址,同时指定进入队列的数目,如果localAddress为null,则可以使用任意地址,如果port为0端口由系统分配。

ServerSocket socketserver=new ServerSocket(2012); 
// 2012 表示服务器要监听的端口号

服务端ServiceSocket重要方法说明:

public Socket accept():等待客户端Socket请求,直到链接被打开,该方法返回一个刚刚打开的连接的客户端Socket对象。
public void close():关闭服务器Socket。
Socket 一般有两种类型:TCP 套接字和 UDP 套接字。TCP 把消息分解成数据包并在接收端以正确的顺序把它们重新装配起来,TCP 还处理对遗失数据包的重传请求减少上层应用数据处理。UDP 不提供装配和重传请求这些功能,它只是向前传送信息包。上层的应用层必须确保消息是完整的,并且是以正确的顺序装配。

TCP服务端工作流程:

1,调用ServiceSocket(int port)创建一个ServiceSocket,并绑定到指定端口上。
2,调用accept(),监听连接请求,如果客户端请求连接则接受连接返回通信套接字。
3,调用Socket类的getOutputStream()和getInputStream()获取输出输入流开始网络数据的发送和接收。
4,调用close()方法关闭套接字。

// 创建一个 ServerSocket 对象 
ServerSocket serverSocket = null;
try {
 // TCP_SERVER_PORT 为指定的绑定端口,为 int 类型
 serverSocket = new ServerSocket(TCP_SERVER_PORT);
 // 监听连接请求
 Socket socket = serverSocket.accept();
 // 写入读 Buffer 中
 BufferedReader in = new BufferedReader(new 
 // 获取输入流
 InputStreamReader(socket.getInputStream()));
 // 放到写 Buffer 中
 BufferedWriter out = new BufferedWriter(new 
 // 获取输出流
 OutputStreamWriter(socket.getOutputStream()));
 // 读取接收信息,转换为字符串
 String incomingMsg = in.readLine() + System.getProperty("line.separator");
 // 生成发送字符串
 String outgoingMsg = "goodbye from port " + TCP_SERVER_PORT + 
 System.getProperty("line.separator");
 // 将发送字符串写入上面定义的 BufferedWriter 中
 out.write(outgoingMsg);
 // 刷新,发送
 out.flush();
 // 关闭
 socket.close();
} catch (InterruptedIOException e) {
 // 超时错误
 e.printStackTrace();
 // IO 异常
} catch (IOException e) {
 // 打印错误
 e.printStackTrace();
} finally {
 // 判定是否初始化 ServerSocket 对象,如果初始化则关闭 serverSocket
 if (serverSocket != null) {
 try {
 serverSocket.close();
 } catch (IOException e) {
 e.printStackTrace();
 }
 }
}

TCP客户端工作流程:

1,调用Socket()创建一个流套接字,并连接到服务端。
2,调用Socket类的getOutputStream()和getInputStream()方法获取输出和输入流开始网络数据的发送和接收。
3,调用close()方法关闭套接字。

try {
 // 初始化 Socket,TCP_SERVER_PORT 为指定的端口,int 类型
 Socket socket = new Socket("localhost", TCP_SERVER_PORT);
 // 获取输入流
 BufferedReader in = new BufferedReader(new 
 InputStreamReader(socket.getInputStream()));
 // 生成输出流
 BufferedWriter out = new BufferedWriter(new
 OutputStreamWriter(socket.getOutputStream()));
 // 生成输出内容
 String outMsg = "TCP connecting to " + TCP_SERVER_PORT + 
 System.getProperty("line.separator"); 
 // 写入
 out.write(outMsg);
 // 刷新,发送
 out.flush();
 // 获取输入流
 String inMsg = in.readLine() + System.getProperty("line.separator");
 Log.i("TcpClient", "received: " + inMsg);
 // 关闭连接
 socket.close();
 } catch (UnknownHostException e) {
 e.printStackTrace();
 } catch (IOException e) {
 e.printStackTrace();
}

UDP 服务端工作的主要步骤:

1,调用DatagramSocket(int port)创建一个数据报套接字,并绑定到指定端口上。
2,调用DatagramPacket(byte[] buf,int length),建立一个字节数组以接收UDP包。
3,调用DatagramSocket类的receive(),接收UDP包。
4,关闭数据报套接字。

// 接收的字节大小,客户端发送的数据不能超过 MAX_UDP_DATAGRAM_LEN 
byte[] lMsg = new byte[MAX_UDP_DATAGRAM_LEN];
// 实例化一个 DatagramPacket 类
DatagramPacket dp = new DatagramPacket(lMsg, lMsg.length);
// 新建一个 DatagramSocket 类
DatagramSocket ds = null;
try {
 // UDP 服务器监听的端口 
 ds = new DatagramSocket(UDP_SERVER_PORT);
 // 准备接收数据 
 ds.receive(dp);
} catch (SocketException e) {
 e.printStackTrace();
} catch (IOException e) {
 e.printStackTrace();
} finally {
 // 如果 ds 对象不为空,则关闭 ds 对象
 if (ds != null) {
 ds.close();
 }
}

UDP 客户端工作的主要步骤:

1,调用DatagramSocket()创建一个数据包套接字。
2,调用DatagramPacket(byte[]buf,int offset,int length,InetAddress address,int port),建立要发送的 UDP 包。
3,调用 DatagramSocket 类的 send() 发送 UDP 包。
4,关闭数据报套接字。

// 定义需要发送的信息
String udpMsg = "hello world from UDP client " + UDP_SERVER_PORT;
// 新建一个 DatagramSocket 对象
DatagramSocket ds = null;
try {
 // 初始化 DatagramSocket 对象
 ds = new DatagramSocket();
 // 初始化 InetAddress 对象
 InetAddress serverAddr = InetAddress.getByName("127.0.0.1");
 DatagramPacket dp;
 // 初始化 DatagramPacket 对象
 dp = new Datagram
 Packet(udpMsg.getBytes(), udpMsg.length(), serverAddr, UDP_SERVER_PORT);
 // 发送
 ds.send(dp);
} 
// 异常处理
// Socket 连接异常
catch (SocketException e) { 
 e.printStackTrace();
// 不能连接到主机
}catch (UnknownHostException e) { 
 e.printStackTrace();
// 数据流异常
} catch (IOException e) { 
 e.printStackTrace();
// 其他异常
} catch (Exception e) { 
 e.printStackTrace();
} finally {
 // 如果 DatagramSocket 已经实例化,则需要将其关闭
 if (ds != null) {
 ds.close();
 }
}
上一篇下一篇

猜你喜欢

热点阅读