大数据开发学习文档(分布式文件系统的实现,大数据生态圈学习文档等): 文章专栏(点击跳转)
文档目录
一文读懂Java Socket编程
1、什么是Socket?
百度百科说:
所谓Socket (套接字),就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。从所处的地位来讲,套接字上联应用进程,下联网络协议栈,是应用程序通过网络协议进行通信的接口,是应用程序与网络协议栈进行交互的接口。
接下来说人话:
Socket(套接字)可以看成是两个网络应用程序进行通信时,各自通信连接中的端点,这是一个逻辑上的概念。例如A、B进行通信,他们发出数据与接收数据的地方就是各自的通信端点,即套接字(Socket)。
2、Socket 通信原理
它是网络环境中进程间通信的API(应用程序编程接口),也是可以被命名和寻址的通信端点,使用中的每一个套接字都有一个与之相连进程(通过端口号标识)。
通信时其中一个网络应用程序将要传输的一段信息写入它所在主机的 Socket中,该 Socket通过与网络接口卡(NIC)相连的传输介质将这段信息送到另外一台主机的 Socket中,使对方能够接收到这段信息。
Socket是面向客户/服务器模型而设计的。通信的一方扮演客户机的角色,另一方扮演服务器的角色。服务器在运行中一直监听套接字指定的传输层端口,并等待着客户机的连接请求(Connect)。当服务器端收到客户机发来的连接请求以后,服务器会接受客户机的连接请求,双方建立连接后,就可进行数据的传递。
Socket(套接字)包括 IP 地址和端口号两个部分,提供向应用层进程传送数据包的机制。通过网络通信的每对进程需要使用 一对 套接字。不同的进程之间的通信所使用的套接字是不一样的,套接字可以用来区分不同的进程之间的数据传输。
3、Java Socket编程
下面的部分我将讲解ServerSocket与Socket并通过一些代码示例,讲解一下如何使用socket编写Client和Server端的程序。
3.1 ServerSocket与Socket
3.1.1 Socket
构造函数
public Socket(String host, int port) throws UnknownHostException, IOException
//此方法尝试连接到指定端口上的指定服务器。如果此构造函数未引发异常,则连接成功并且客户端连接到服务器。
public Socket(InetAddress host, int port) throws IOException
//此方法与前一个构造函数相同,只是主机由InetAddress对象表示。
public Socket(String host, int port, InetAddress localAddress, int localPort) throws IOException
//连接到指定的主机和端口,在指定地址和端口的本地主机上创建套接字。
public Socket(InetAddress host, int port, InetAddress localAddress, int localPort) throws IOException
//此方法与前一个构造函数相同,只是主机由InetAddress对象表示。
public Socket()
//创建一个未连接的套接字。使用connect()方法将此套接字连接到服务器。
Socket方法
//将套接字连接到指定的主机。仅当使用无参数构造函数实例化Socket时才需要此方法。
public void connect(SocketAddress host, int timeout) throws IOException
此外:
getInetAddress(); //远程服务端的IP地址
getPort(); //远程服务端的端口
getLocalAddress() //本地客户端的IP地址
getLocalPort() //本地客户端的端口
getInputStream(); //获得输入流
getOutStream(); //获得输出流
3.1.2 ServerSocket
构造函数
public ServerSocket(int port) throws IOException
//尝试创建绑定到指定端口的服务器套接字。如果端口已被另一个应用程序绑定,则会发生异常。
public ServerSocket(int port, int backlog) throws IOException
//与前上面构造函数类似,backlog参数指定要在等待队列中存储的传入客户端的数量。
public ServerSocket(int port, int backlog, InetAddress address) throws IOException
//与前一个构造函数类似,InetAddress参数指定要绑定的本地IP地址。InetAddress用于可能具有多个IP地址的服务器,允许服务器指定哪个IP地址接受客户端请求。
public ServerSocket() throws IOException
//创建未绑定的服务器套接字。使用此构造函数时,在准备绑定服务器套接字时使用bind()方法。
ServerSocket方法
public int getLocalPort()
//返回服务器套接字正在侦听的端口。如果在构造函数中传入0作为端口号并让服务器自己打开端口,则此方法很有用。
public Socket accept() throws IOException
//等待传入的客户端。假设已使用setSoTimeout()方法设置超时值,此方法将阻塞,直到客户端连接到指定端口上的服务器或套接字超时。否则,此方法无限期地阻塞。
public void setSoTimeout(int timeout)
//设置服务器套接字在accept()期间等待客户端的时间的超时值。
public void bind(SocketAddress host, int backlog)
//将套接字绑定到SocketAddress对象中的指定服务器和端口。如果已使用无参数构造函数实例化ServerSocket,请使用此方法。
当ServerSocket调用accept()时,在客户端连接之前不会返回。客户端连接后,ServerSocket在未指定的端口上创建一个新的Socket,并返回对此新Socket的引用。客户端和服务器之间现在存在TCP连接,并且可以开始通信。
3.2 服务器与客户端建立连接
J2SE API的java.net包中包含一组类和接口,它们提供低级别的通信详细信息,开发者可编写专注于解决手头问题的程序。
java.net包提供对两种常见网络协议的支持:
- TCP代表传输控制协议,它允许两个应用程序之间的可靠通信。TCP通常用于Internet协议,称为TCP/IP。
- UDP代表用户数据报协议,这是一种无连接协议,允许在应用程序之间传输数据包。
java.net.Socket类表示一个套接字,java.net.ServerSocket类为Server程序提供了一种监听Client并与它们建立连接的机制。使用套接字在两台计算机(或同一计算器的不同进程)之间建立TCP连接时,会发生以下步骤:
- Server实例化ServerSocket对象,表示要在哪个端口号上进行通信。
- Server调用ServerSocket类的accept()方法。此方法等待,直到Client连接到给定端口上的Server。
- 在Server等待之后,Client实例化Socket对象,指定要连接的Server名称(IP地址)和端口号。
- Socket类的构造函数尝试将Client连接到指定的Server和端口号。如果建立了通信,则Client现在具有能够与Server通信的Socket对象。
- 在Server端,accept()方法返回对连接到客户端套接字的服务器上的新套接字的引用。
我们可以看到,在服务器端建立套接字使用的是ServerSocket()方法而在客户端则是直接使用Socket()方法,那么这两个方法的区别在哪里呢?
一句话:
Server应用程序使用java.net.ServerSocket类来获取端口并侦听客户端请求。
Client应用程序通过实例化一个java.net.Socket类来获取Socket对象,而Server从accept()方法的返回值获取Socket对象。
**代码示例**
//实例化ServerSocket对象
ServerSocket serverSocket = new ServerSocket(Config.META_SERVRE_PORT) ;
//调用accept()方法等待Client请求连接
Socket clientSocket = serverSocket.accept();
// Client实例化Socket对象,指定要连接的Server IP地址和端口号
Connection connection = new Connection(META_SERVRE_HOST, METADATA_SERVER_PORT);
//Connection对象构造函数如下 ↓
public Connection(String host, int port) throws IOException {
this.host = host;
this.port = port;
socket = new Socket(host,port);
// 获取输入流和输出流
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
}
此时Server和Client要进行通信,可以使用I/O流进行通信。每个套接字都有一个OutputStream和一个InputStream。客户端的OutputStream连接到服务器的InputStream,客户端的InputStream连接到服务器的OutputStream。
(TCP是双向通信协议,所以可以实现同时跨两个流传送数据 ↑ )
3.3通信示例(分布式文件系统心跳链接)
Server端:
Client端:
4、结语
//TODO:
InputStream和OutputStream流的操作;
实现一个简单的分布式文件系统(基于Hadoop) 操作文档;
待更新…
最近在写一个简单的分布式文件操作系统,用到了网络编程Socket的知识,虽然不影响写项目,但是还是想着认真对待,毕竟以后肯定还会用到这方面的知识。所以将自己整理的学习文档上传至此,希望对大家的学习也能有所帮助。
15点21分 2023年11月25日
欢迎大家积极讨论,如有错误,还请不吝赐教!