galaxy
  • Introduction
  • knowledge
    • JAVA
      • 多态
      • Socket
      • Servlet
      • HashMap
      • TCP
      • DelayQueue
      • Java反射
      • Java Proxy 和 CGLIB 动态代理
      • JVM
        • 类生命周期
        • JVM内存模型
        • 类加载器与双亲委派模型
        • JVM中堆和栈的区别
      • java.time
    • Spring
      • 常用注解
        • @Transactional
      • Spring Data JPA
      • AOP
      • IOC/DI
      • Spring 事务
      • Spring Boot 启动原理解析
      • Spring MVC
        • Spring MVC 2
      • MVC
    • 分布式
      • RPC框架
      • MQ
      • dubbo
        • 环境部署
        • demo
      • 分布式RPC框架性能大比拼
      • 序列化
      • ZK
        • 本地安装zk
        • ZK详解
      • 分布式
        • 分布式锁
      • 限流熔断技术
    • DB
      • Mysql
        • 索引
      • 事务
      • 数据库连接池
        • 工作原理
        • 连接池技术背景
        • 百度百科
        • 主流数据库连接池
      • MongoDB
        • 适用场景
        • MongoDB Java异步驱动快速指南
        • 异步Mongo驱动的性能测试
        • 使用规范
        • 使用场景2
      • Spring Data JPA
      • 数据库设计三大范式
      • 存储过程
      • 视图
      • 乐观锁与悲观锁
      • 分库分表
      • Redis3
        • 其它
        • Redis
        • 场景
        • 分布式及其它
    • Test
      • NGrinder
      • QPS与并发数
    • 并发编程
      • volatitle
      • 锁
      • ThreadLocal
      • AQS
      • CAS
      • RateLimiter
    • 线程池
      • Executors
      • ScheduledThreadPoolExecutor
      • 终止线程池原理
      • demo
  • MST目录
    • 算法&数据结构
      • 算法
      • 数据结构
      • 算法题
      • 经典算法
  • Tool
    • Git
    • Netty5
      • 一些案例
      • Netty源码分析
        • 一、服务器绑定过程分析
        • 二、线程模型分析
        • 三、Channel如何注册OP_ACCEPT, OP_READ, OP_WRITE
        • 四、事件分发模型
        • 五、ByteBuf缓冲区
        • 六、CodeC编解码分析
        • 七、异步执行Future和Promise
      • Netty5.0架构剖析和源码解读
    • idea
  • issue
    • Connection reset
    • 该如何从 Java 8 升级到 Java 10
    • 阿里巴巴为什么不用 ZooKeeper 做服务发现
  • Linux
    • command
Powered by GitBook
On this page
  • socket (计算机专业术语)
  • 举例说明
  • 现象解释
  • 连接过程
  • 常用函数

Was this helpful?

  1. knowledge
  2. JAVA

Socket

Previous多态NextServlet

Last updated 6 years ago

Was this helpful?

百度百科:

socket (计算机专业术语)

网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。

建立网络通信连接至少要一对端口号(socket)。socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口;HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力。

Socket的英文原义是“孔”或“插座”。作为BSD UNIX的进程通信机制,取后一种意思。通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。Socket正如其英文原义那样,像一个多孔插座。一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电, 有的提供110伏交流电,有的则提供有线电视节目。 客户软件将插头插到不同编号的插座,就可以得到不同的服务。

举例说明

Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求。

以J2SDK-1.3为例,Socket和ServerSocket类库位于java.net包中。ServerSocket用于服务器端,Socket是建立网络连接时使用的。在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。不管是Socket还是ServerSocket它们的工作都是通过SocketImpl类及其子类完成的。

现象解释

最重要的是,Socket是面向客户/服务器模型而设计的,针对客户和服务器程序提供不同的Socket系统调用。客户随机申请一个Socket(相当于一个想打电话的人可以在任何一台入网电话上拨号呼叫),系统为之分配一个Socket号;服务器拥有全局公认的Socket,任何客户都可以向它发出连接请求和信息请求(相当于一个被呼叫的电话拥有一个呼叫方知道的电话号码)。

Socket利用客户/服务器模式巧妙地解决了进程之间建立通信连接的问题。服务器Socket半相关为全局所公认非常重要。读者不妨考虑一下,两个完全随机的用户进程之间如何建立通信?假如通信双方没有任何一方的Socket固定,就好比打电话的双方彼此不知道对方的电话号码,要通话是不可能的。

连接过程

根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认。

(1)服务器监听:是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。

(2)客户端请求:是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。

(3)连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。

常用函数

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class SocketServer {
    public static String _pattern = "yyyy-MM-dd HH:mm:ss SSS";
    public static SimpleDateFormat format = new SimpleDateFormat(_pattern);
    // 设置超时间
    public static int _sec = 0;

    public static void main(String[] args) {
        System.out.println("----------Server----------");
        System.out.println(format.format(new Date()));

        ServerSocket server;
        try {
            server = new ServerSocket(8001);
            System.out.println("监听建立 等你上线\n");

            Socket socket = server.accept();
            System.out.println(format.format(new Date()));
            System.out.println("建立了链接\n");

            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            socket.setSoTimeout(_sec * 1000);
            System.out.println(format.format(new Date()) + "\n" + _sec + "秒的时间 快写\n");

            System.out.println(format.format(new Date()) + "\nClient:" + br.readLine() + "\n");

            Writer writer = new OutputStreamWriter(socket.getOutputStream());

            System.out.println(format.format(new Date()));
            System.out.println("我在写回复\n");

            writer.write("收到\n");

            Thread.sleep(10000);
            writer.flush();

            System.out.println(format.format(new Date()));
            System.out.println("写完啦 你收下\n\n\n\n\n");
        } catch (SocketTimeoutException e) {
            System.out.println(format.format(new Date()) + "\n" + _sec + "秒没给我数据 我下啦\n\n\n\n\n");
            e.printStackTrace();
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class SocketClient {
    public static String _pattern = "yyyy-MM-dd HH:mm:ss SSS";
    public static SimpleDateFormat format = new SimpleDateFormat(_pattern);
    // 设置超时间
    public static int _sec = 5;

    public static void main(String[] args) {
        System.out.println("----------Client----------");

        Socket socket = null;
        try {
            // 与服务端建立连接
            socket = new Socket("127.0.0.1", 8001);
            socket.setSoTimeout(_sec * 1000);

            System.out.println(format.format(new Date()));
            System.out.println("建立了链接\n");

            // 往服务写数据
            Writer writer = new OutputStreamWriter(socket.getOutputStream());

            System.out.println(format.format(new Date()));
            System.out.println("我在写啦\n");
            Thread.sleep(10000);
            writer.write("有没有收到\n");

            System.out.println(format.format(new Date()));
            System.out.println("写完啦 你收下\n");

            writer.flush();

            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            System.out.println(format.format(new Date()) + "\n" + _sec + "秒的时间 告诉我你收到了吗\n");

            System.out.println(format.format(new Date()) + "\nServer:" + br.readLine());

        } catch (SocketTimeoutException e) {
            System.out.println(format.format(new Date()) + "\n" + _sec + "秒没收到回复 我下啦\n\n\n\n\n");
            e.printStackTrace();
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Socket利用网间网通信设施实现。至此,我们对Socket进行了直观的描述。抽象出来,Socket实质上提供了进程通信的端点。进程通信之前,双方首先必须各自创建一个端点,否则是没有办法建立联系并相互通信的。在网间网内部,每一个Socket用一个半相关描述:(协议,本地地址,本地端口)。一个完整的Socket有一个本地唯一的Socket号,由操作系统分配。

进程通信
https://baike.baidu.com/item/socket/281150?fr=aladdin