TCP通信

TCP协议:传输控制层协议,面向有链接,数据可靠

Socket

Socket通常也称作“套接字”,用于描述IP地址和端口,是一个通信链的句柄。在Internet上的主机一般运行了多个服务软件,同时提供集中服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。

应用程序通常通过“套接字”向网络发出请求或应答网络请求。Socket和Serversocket类库位于java.net包中。ServerSocket用于服务端,Socket是创建网络连接时使用的。在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。

获取本地地址和端口号

java.net.Scoket为套接字类,其提供了很多方法,其中我们可以通过获取socket获取本地的地址以及端口号。

  • 其方法为:
    int getLocalPort(); 用于获取本地使用的端口号
    InetAddress getLocalAddress(); 用于获取套接字绑定的本地地址
    使用InetAddress获取本地的地址方法:
    String getCanonicalHostName(); 获取此IP地址的完全限定名
    String getHostAddress(); 返回IP地址字符串(以文本表现形式)
  • 代码如下:
public static void main(String[] args) throws UnknownHostException, IOException {
		Socket socket = new Socket("localhost",8088);
		InetAddress add = socket.getLocalAddress();//获取本地信息
		System.out.println(add.getCanonicalHostName());// 获取此IP地址的完全限定名
		System.out.println(add.getHostAddress());//用于获取套接字绑定的本地地址
		System.out.println(socket.getLocalPort());//用于获取本地使用的端口号
		socket.close();
  }

获取远程地址和端口号

Socket也提供了获取远端的地址以及端口号的方法:

  • 其方法为:
    int getPort(); 用于获取远端使用的端口号
    InetAddress getInetAddress(); 用于获取套接字绑定的远端地址
  • 代码如下:
public static void main(String[] args) throws UnknownHostException, IOException {
		Socket socket = new Socket("localhost",8088);
		InetAddress inetadd = socket.getInetAddress();//获取远端信息
		System.out.println(inetadd.getCanonicalHostName());// 获取此IP地址的完全限定名
		System.out.println(inetadd.getHostAddress());//用于获取套接字绑定的远端地址
		System.out.println(socket.getPort());//用于获取远端使用的端口号
		socket.close();
  }

获取网络输入/输出流

通过Socket获取输入流与输出流,这两个方法是使用Socket通讯的关键方法。封装了TCP协议的Socket是基于流进行通讯的,所以我们在创建了双方连接后,只需要获取相应的输入与输出流即可实现通讯。

  • 其方法为:
    InputStream getInputStream(); 该方法用于返回此套接字的输入流。
    OutputStream getOutputStream(); 该方法用于返回此套接字的输出流
  • 代码如下:
public static void main(String[] args) throws UnknownHostException, IOException {
		Socket socket = new Socket("localhost",8088);
    InputStream in = socket.getInputStream();
    OutputStream out = socket.getOutputStream();
  }

close方法

当使用Socket进行通讯完毕后,要关闭Socket以释放系统资源。

  • 其方法为:
    void close(); 关闭Socket以释放资源

当关闭了该套接字后也会同时关闭由此获取的输入流与输出流。

 

Scoket通讯模块

Server端ServerSocket监听

java.net.ServerSocket是运行于服务端应用程序中,通过创建ServerSocket需要指定服务端口号,之后监听Socket的连接。

  • 其方法为:
    Socket accept();

该方法是一个阻塞方法,直到一个客户端通过Socket连接后,accept会封装一个Socket,该Socket封装的表示该客户端的有关信息,通过这个Socket与客户端进行通信。

  • 代码如下:
//创建ServerSocket并申请服务端口8088
	ServerSocket server = new ServerSocket(8088);
	//方法会产生阻塞,知道某个Socket连接,并返回请求连接的Socket
	Socket socket = server.accept();

Client端的Socket连接

当服务端ServerSocket调用accept方法阻塞等待客户端连接后,可以通过在客户端应用程序中创建Socket来向服务器发起连接。

{% note warning flat %}创建Socket的同时就发起连接,若连接异常会抛出异常,我们通常创建Socket时会传入服务端的地址及服务端口号。{% endnote %}

  • 代码如下:
//参数1:服务端的IP地址,参数2:服务端的服务端口
	Socket socket = new Socket("localhost",8088);

C-S端通信模块

C-S的全程为(Client-Server):客户端-服务器端

客户端与服务端通信模型如下:

  • 步骤如下:
  1. 服务端ServerSocket
  2. 通过调用ServerSocket的accept方法监听客户端的连接
  3. 客户端创建Socket并指定服务端的地址以及端口来建立与服务端的连接
  4. 当服务端accept发现客户端连接后,后去对应该客户端的Socket
  5. 双方通过Socket分别获取对应的输入与输出流进行数据通讯
  6. 通讯结束后关闭连接5

Server端多线程模型

可以创建一个线程类,并将客户端交互的工作全部委托给线程处理,这样就可以实现当一个客户端连接后,启动一线程来负责与客户端的交互,这样我们就可以实现循环不断的监听其他客户端连接。

 

UDP通信

UDP协议:用户数据报协议,面向无连接,数据不可靠

DatagramPacket

创建接受包

DatagramPacket:UDP数据报给予IP建立,没太主机有65535个端口号可以使用。数据报中字结束限制为65535-8,包含8字节的头信息。

  • 构造接受包:
    DatagramPacket(byte[] buf, int length); 将数据报中Length长的数据装进Buf数组。
    DatagramPacket(byte[] buf, int offset, int lenth); 将数据报中从Offset开始、Length长的数据装进Buf数组。

创建发送包

  • 构造发送包:
    DatagramPacket(byte[] buf, int length, InetAddress clientAddress, int clientPort); 从buf数组中取出Length长的数据创建数据报对象,目标是clientAddress地址、clientPort端口,常用来发送数据给客户端。
    DatagramPacket(byte[] buf, int offset, int length, InetAddress clientAddress, int clientPort); 从buf数组中,取出offset开始、Length长的数据创建数据报对象,目标是clientAddress地址、clientPort端口,常用来发送数据给客户端。

DatagramSocket

服务端接受

DatagramSocket用于接受和发送UDP的Socket实例。

  • 其语法格式为:DatagramSocket(int port);

创建实例,并固定监听Port端口的报文。

  • 其中方法:
    receive (DatagramPacket d); 接受数据报文到d中,receive方法产生“阻塞”。会一直等待直到数据被读取到。

客户端发送

无参的构造方法DaragramSocket()通常用于客户端编程,它并没有特定监听的端口,仅仅使用一个临时的,程序会让操作系统分配一个可用的端口。

  • 其中方法:
    send (DatagramPacket dp); 该方法用于发送报文到目的地。

 


❤️ END ❤️