Sockets(套接字)被定义为通信端点。

在网络上通信的一对进程使用一对套接字---每个进程对应一个Socket

一个Sockets(套接字)由一个IP地址和端口号连接形成。

通常,套接字使用客户机-服务器架构。服务器端通过监听指定的端口,等待客户端请求的到来。一旦收到请求,服务器接收来自客户端套接字的连接,从而完成连接。

实现特定服务的服务器(如telnet、FTP和HTTP)侦听众所周知的端口(telnet服务器监听端口23;FTP服务器监听端口21;而web或HTTP则侦听端口80。)所有的小于1024的端口都被认为是知名的端口,我们可以使用它们来实现标准的服务。

当客户端进程发起一个连接请求。,它回被主机分配一个端口号。这些断口号是大于1024的任意数字。

比如一个客户机在IP为146.86.5.20的主机X上,他想与在IP为161.25.19.8的web服务器(监听端口80)建立连接。客户机可能绑定到的端口是1625.连接由两个Socket组成:①主机X上的(146.86.5.20:1625)②web服务器上的(161.25.19.8:80)。在两个主机上移动的包可以通过目标端口号,被分送给合适的进程。

所有的连接必须是唯一的。因此,如果在主机X上的另一个进程也想要与这个相同的web服务器建立另一个连接的话,他可能会被分配一个大于1024但不是1625的端口,这确保了所有的连接都由一对唯一的Socket(套接字)组成。

Java提供了3种不同类型的Sockets:

  • Connection-oriented(TCP) Socket:面向连接的Socket,它是用Socket.class类实现的
  • Connectionless( UDP ) Sockets:无连接传输模式的Socket,使用DatagramSocket类实现的
  • 最后是MulticastSocket,它是MulticastSocket的子类,该模式运行数据被发送到多个接受者。

下面例子使用面向连接的Socket来演示:

该操作允许客户端从服务器请求当前日期和时间。服务器监听端口6013,尽管端口可以是任意大于1024的数字。当接收到连接时,服务器将日期和时间返回给客户端。

服务器代码:

import java.net.*;
import java.io.*;

public class DateServer
{
    public static void main(String[] args)  {
        try {
            //1. 创建服务器Socket,并将监听端口6013
            ServerSocket sock = new ServerSocket(6013);

            //2. 服务器通过accept()方法开始监听端口
            while (true) {
                //服务器会在accept()方法阻塞,等到客户端的连接
                Socket client = sock.accept();
                // 当有客户端连接的时候,accept()会返回一个服务器可用于与客户端通信的套接字。

                PrintWriter pout = new PrintWriter(client.getOutputStream(), true);
                // 向客户端写会响应
                pout.println(new java.util.Date().toString());

                // 关闭连接,并重新监听其他的连接请求
                client.close();
            }
        }
        catch (IOException ioe) {
                System.err.println(ioe);
        }
    }
}

客户端代码:

import java.net.*;
import java.io.*;

public class DateClient
{
    public static void main(String[] args)  {
        try {
            //客户端通过一个连接到服务端所监听的端口的socket来与服务器端通信
            Socket sock = new Socket("127.0.0.1",6013);
            //一旦连接建立,那么而已通正常的I/O流语句来读
            InputStream in = sock.getInputStream();
            BufferedReader bin = new BufferedReader(new InputStreamReader(in));

            String line;
            while( (line = bin.readLine()) != null)
                System.out.println(line);
            //当读取完数据,可以关闭连接并退出    
            sock.close();
        }
        catch (IOException ioe) {
                System.err.println(ioe);
        }
    }
}

127.0.0.1是一个特殊的IP,也被称为回环(loopback)。当一个计算机引用到了127.0.0.1这个IP,其实他就是引用到了自己。此机制允许在同一主机上的客户机和服务器使用TCP / IP协议进行通信。

使用sockets进行通信——尽管很通用和有效——但是这属于较为低级的分布式进程通信。 一个原因是Socket(套接字)只允许在通信线程之间交换非结构化的字节流 。客户端或服务器应用程序需要负责加上数据结构。

接下来将RPC(远程过程调用)和RMI(远程方法调用)

results matching ""

    No results matching ""