Kotlin网络编程(3)TCP Socket 低层次网络编程

  • TCP Socket 通信概念
  • TCP Socket 通信过程
  • Socket 类
  • ServerSocket 类
  • 案例:文件上传工具

  TCP 是面向连接的可靠数据传输协议。TCP 通信过程类似于打电话,电话接通后双方才能通话,在挂断电话之前,电话一直占线。TCP 接连一旦建立起来,会一直占用,知道关闭连接。此外,TCP 为了保证数据的正确性,会重发一切没有收到的数据,还会对数据内容进行验证并保证数据传输的正确顺序。因此 TCP 协议对系统资源有很高的要求。

一、TCP Socket 通信概念

  Socket 是网络上的两个程序,通过一个双向的通信连接,实现数据的交流。这个链路的一端称为一个 Socket。Socket 通常用来实现客户端和服务端的连接。Socket 是 TCP/IP 协议的一个十分流行的编程接口,一个 Socket 有一个 IP 地址和一个端口号唯一确定。一旦建立连接,Socket 还会包含本机和远程主机的 IP 地址和远端口号,Socket 是成对出现的。

二、TCP Socket 通信过程

  使用 Socket 进行 C/S 结构编程的通信过程如下:


TCP Socket 通信过程

  服务器端监听某个端口是否有连接请求,此时服务器端程序处于阻塞状态,知道客户端向服务器端发出连接请求,服务器端接收客户端请求,服务器会应答请求并处理请求,然后将结果应答给客户端,这样就会建立连接。一旦连接建立起来,通信 Socket 可以获得输入输出流对象。借助于输入输出流对象就可以实现服务器与客户端的通信,最后不要忘记关闭 Socket 和释放一些资源(包括关闭输入输出流)。

三、Socket 类

  java.net 包为 TCP Socket 编程提供了两个核心类:SocketServerSocket,分别用来表示双向连接的客户端和服务器端。

  下面是Socket类常用的构造函数

  • Socket(address: InetAddress!, port: Int):创建 Socket 对象,并指定远程主机 IP 地址和端口号;

  • Socket(address: InetAddress!, port: Int, localAddr: InetAddress!, localPort: Int):创建 Socket 对象,并指定远程主机 IP 地址、端口号以及本机的 IP 地址 (localAddr) 和 端口号 (localPort);

  • Socket(host: String!, port: Int):创建 Socket 对象,并指定远程主机名和端口号,IP 地址为 null,null 表示回送地址,即 127.0.0.1

  • Socket(host: String!, port: Int, localAddr: InetAddress!, localPort: Int):创建 Socket 对象,并指定远程主机、端口号以及本机的 IP 地址 (localAddr) 和 端口号 (localPort)。host 为主机名,IP 地址为 null,null 表示回送地址,即 127.0.0.1

  提示:“数据类型!” 表示 “平台类型”,String! 表示 String 或 String?。什么是平台类型?

  Socket 其他的常用函数和属性如下

  • getInputStream() 函数:通过此 Socket返回输入流对象。

  • getOutputStream() 函数:通过此 Socket返回输出流对象。

  • port: Int 属性:返回 Socket连接到的远程端口。

  • localPort: Int 属性:返回 Socket绑定到本地端口。

  • inetAddress 属性:返回 Socket连接地址。

  • localAddress 属性:返回 Socket绑定的本地地址。

  • isClosed 属性:判断返回 Socket是否处于关闭状态。

  • isConnected 属性:判断返回 Socket是否处于连接状态。

  • close() 函数:关闭 Socket。

  注意:Socket 与 流所占用的资源类似,不能通过 Java 虚拟机的垃圾收集器回收,需要程序员释放。释放的方式有两种,一种是可以在 finally 代码块调用 close() 函数关闭 Socket,释放流所占用的资源。另一种是通过自动资源管理技术释放资源,SocketServerSocket 都实现了 AutoCloseable 接口,所以 kotlin 中可以使用 use 函数。

四、ServerSocket 类

  ServerSocket 类常用的构造函数

  • ServerSocket(port: Int, maxQueue: Int)。创建绑定到特定端口的服务器 Socket。maxQueue 设置连接请求的最大队列长度,入多队列满时,则拒绝该连接。默认值是 50

  • ServerSocket(port: Int)。创建绑定到特定端口的服务器 Socket。连接请求的最大队列长度是 50

  ServerSocket 其他的常用函数和属性如下

  • getInputStream() 函数:通过此 Socket返回输入流对象。

  • getOutputStream() 函数:通过此 Socket返回输出流对象。

  • isClosed 属性:判断返回 Socket是否处于关闭状态。

  • isConnected 属性:判断返回 Socket是否处于连接状态。

  • accept() 函数:侦听并接收到 Socket 的连接。此函数在建立连接之前一直是阻塞状态 。

  ServerSocket 类本身不能直接获得 I/O 流对象,而是通过 accept() 函数返回 Socket 对象,通过 Socket 对象取得 I/O 流对象,进行网络通信。另外,ServerSocket 也实现了 AutoCloseable 接口,通过自动资源管理技术关闭 ServerSocket

五、案例:文件上传工具

  • 服务器端代码:
fun main(args: Array<String>?) {
    println("服务器端运行...")
    ServerSocket(8080).use { server ->
        server.accept().use { socket ->
            BufferedInputStream(socket.getInputStream()).use { bis ->
                FileOutputStream("./TestDir/subDir/fxy.png").use { fos ->
                    bis.copyTo(fos)
                    println("接收完成!")
                }
            }
        }
    }
}

  注意:ServerSocketaccept() 函数阻塞当前线程,所以一般会是在子线程中执行 accept() 函数。

  • 客户端代码:
fun main(args: Array<String>?) {
    println("客户端运行...")
    Socket("127.0.0.1", 8080).use { socket ->
        BufferedOutputStream(socket.getOutputStream()).use { bos ->
            FileInputStream("./TestDir/fxy.png").use { fis ->
                fis.copyTo(bos)
                println("上传成功!")
            }
        }
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,723评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,003评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,512评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,825评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,874评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,841评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,812评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,582评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,033评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,309评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,450评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,158评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,789评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,409评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,609评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,440评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,357评论 2 352

推荐阅读更多精彩内容

  • 7.2 面向套接字编程我们已经通过了解Socket的接口,知其所以然,下面我们就将通过具体的案例,来熟悉Socke...
    lucas777阅读 1,176评论 0 2
  • 1 网络编程----TCPNo24 【 public class Server { public static...
    征程_Journey阅读 1,257评论 0 4
  • JAVA套接字之TCP编程 1 TCP协议 TCP是面向谅解的协议。所谓连接,就是两个对等实体为进行数据通信而进行...
    yanzhelee阅读 1,149评论 0 3
  • 计算机网络概述 网络编程的实质就是两个(或多个)设备(例如计算机)之间的数据传输。 按照计算机网络的定义,通过一定...
    蛋炒饭_By阅读 1,217评论 0 10
  • 她推开窗户,指着旋转的星空说——那就是你的画,那就是你的小说。 第一次读蔡骏的小说,断断续续抽离和再次投入情节环境...
    任一白阅读 358评论 1 2