博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java之Socket
阅读量:6934 次
发布时间:2019-06-27

本文共 4014 字,大约阅读时间需要 13 分钟。

简述

  Java中Socket分为普通Socket和NioSocket两种,这里介绍Socket。

  我们可以把Socket比作两个城市间的交通工具,有了它可以在两城之间来回穿梭,交通工具有很多种,每种交通工具也有相应的交通规则。Socket也一样,也有多种。大多情况下使用的是TCP/IP的流套接字,它是一种稳定的通信协议。()

  Java中的网络通信是通过Socket实现的,Socket分为ServerSocket和Socket两大类,ServerSocket用于服务端,通过accept方法监听请求,监听到请求后返回Socket,Socket用于具体完成数据传输,客户端直接使用Socket发起请求并传输数据。

  ServerSocket的使用可以分为三步:

  1. 创建ServerSocket。ServerSocket的构造方法一共有5个,通常用的是ServerSocket(int port),只需要端口号(port)即可。
  2. 调用创建出来的ServerSocket的accept方法进行监听。accept方法时阻塞方法,也就是说调用accept方法后程序会停下来等待连接请求,在接收到请求之前程序将不会往下走。当接收到请求后accept方法会返回一个Socket。
  3. 使用accept方法返回的Socket与客户端进行通信。

栗子

Client:

1 package IO; 2  3 import java.io.*; 4 import java.net.Socket; 5 import java.util.Date; 6  7 /** 8  * Created by zhengbin06 on 2017/2/2. 9  */10 public class Client {11     public static void main(String[] args) {12         String msg = "Client Data";13         try {14             Socket socket = new Socket("127.0.0.1", 9090);15 16             // 先写、再读17             PrintWriter printWriter = new PrintWriter(socket.getOutputStream());18             // 发送数据19             printWriter.println(msg);20             printWriter.flush();21             // 获得服务端返回的数据22             BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));23             String line = bufferedReader.readLine();24             System.out.println("received from server: " + line + "\ttime=" + new Date().getTime());25             // 关闭资源26             printWriter.close();27             bufferedReader.close();28             socket.close();29         } catch (IOException e) {30             e.printStackTrace();31         }32     }33 }

Server:

1 package IO; 2  3 import java.io.BufferedReader; 4 import java.io.IOException; 5 import java.io.InputStreamReader; 6 import java.io.PrintWriter; 7 import java.net.ServerSocket; 8 import java.net.Socket; 9 import java.util.Date;10 11 /**12  * Created by zhengbin06 on 2017/2/2.13  */14 public class Server {15     private static Socket socket = null;16     private static ServerSocket serverSocket = null;17     public static void main(String[] args) throws IOException {18         BufferedReader bufferedReader = null;19         PrintWriter printWriter = null;20         try {21             // 创建一个ServerSocket监听9090端口22             serverSocket = new ServerSocket(9090);23             while (true) {24                 System.out.println("开始等待请求。。。。");25                 // 等待请求26                 // 监听并接受到此套接字的连接。此方法在连接传入之前一直阻塞。27                 socket = serverSocket.accept();28                 System.out.println("接收到请求:" + socket.toString() + "\ttime=" + new Date().getTime());29                 // 接收到请求后使用socket进行通信, 创建BufferedReader用于读取数据30                 bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));31                 String line = bufferedReader.readLine();32                 System.out.println("received from client: " + line + "\ttime=" + new Date().getTime());33     34                 // 创建PrintWriter, 用于发送数据35                 printWriter = new PrintWriter(socket.getOutputStream());36                 printWriter.println("received data: " + line + "\ttime=" + new Date().getTime());37                 printWriter.flush();38             }39         } finally {40             // 关闭所有资源41             bufferedReader.close();42             printWriter.close();43             socket.close();44             serverSocket.close();45         }46     }47 }

细节

监听请求:

  当一个新的Socket请求来到时,将为这个连接创建一个新的套接字数据结构,该套接字数据的信息包含的地址和端口正式请求源地址和端口。这个新创建的数据结构将会关联到ServerSocket实例的一个未完成的连接数据结构列表中。注意,这时服务端的与之对应的Socket实例并没有完成创建,而要等到与客户端的3次握手完成后,这个服务端的Socket实例才会返回,并将这个Socket实例对应的数据结构从未完成列表中移动已完成列表中。

数据传输:

  当连接已经建立成功时,服务端和客户端都会拥有一个Socket实例,每个Socket实例都有一个InputStream和OutputStream,并通过这两个对象来交换数据。

  要知道网络I/O都是以字节流传输的,当创建Socket对象时,操作系统将会为InputStream和OutputStream分别分配一定大小的缓存区,数据的写入和读取都是通过这个缓存区完成的。
  写入端将数据写到OutputStream对应的SendQ队列中,当队列填满时,数据将被转移到另一端InputStream的RecvQ队列中,如果这时RecvQ已经满了,那么OutputStream的write方法将会阻塞,直到RecvQ队列有足够的空间容纳SendQ发送的数据。过程如下图所示:

 

转载地址:http://zywnl.baihongyu.com/

你可能感兴趣的文章
CSS3背景线性渐变
查看>>
C++基础——类继承
查看>>
转:不是技术牛人,如何拿到国内IT巨头的Offer
查看>>
Cocoapods安装使用
查看>>
wine 安装.netframework 2.0方法
查看>>
ArcEngine读取数据(数据访问)-转载
查看>>
python3.x的HTMLTestRunner.py文件
查看>>
POJ2391 Ombrophobic Bovines(网络流)(拆点)
查看>>
教程-MessageBox 使用方法
查看>>
信息安全系统设计基础第五周学习总结
查看>>
LINUX内核分析第八周总结:进程的切换和系统的一般执行过程
查看>>
实验一
查看>>
JavaWeb系列之:Servlet
查看>>
【转】java线程系列---Runnable和Thread的区别
查看>>
微信公众号开发之微信JSSDK
查看>>
函数式编程(小练习)
查看>>
Git 创建两个“本地分支”协同工作
查看>>
she
查看>>
JS脚本调试
查看>>
病毒实验二
查看>>