KotlinKotlin TCP客户端
Katorly本文将讲述如何用Kotlin语言写一个最简单的TCP连接,作为客户端连接TCP服务器。
假定我的TCP服务器每次发送一串字符串供客户端接收。
基本连接、断连、接收、发送函数
这里我使用java.net.Socket
这个现成的工具类来实现连接,先声明一个套接字:
然后是输入和输出流:
1 2
| var reader: BufferedReader var writer: PrintWriter
|
接下来就可以开始连接TCP服务器了:
1 2 3 4 5 6
| fun connect() { socket = Socket() socket.connect(InetSocketAddress("192.168.4.1", "8080"), 5000) reader = BufferedReader(InputStreamReader(socket.getInputStream())) writer = PrintWriter(socket.getOutputStream(), true) }
|
然后这里是手动断开与TCP服务器的连接:
1 2 3 4 5
| fun disconnect() { writer.close() reader.close() socket.close() }
|
向TCP服务器发送字符串,这个再简单不过了,而且不用考虑其它类型的变量,直接字符串大法,什么都直接转成字符串来发送:
1 2 3
| fun send(message: String) { writer.println(message) }
|
主动从TCP服务器接收字符串,如果要实现自动接收得新建一个定时器循环调用这个函数:
1 2 3 4 5
| fun receive(size: Int): String { val buffer = CharArray(size) val length = reader.read(buffer) return String(buffer, 0, length) }
|
到这里,一个最基础的Kotlin TCP客户端代码就完成了。
发送心跳包检测连接是否丢失
此外,还可以加入一个isConnected
变量,来实时检测TCP连接是否丢失。当我们连接上TCP服务器时,如果TCP服务器关闭或发生了其它异常导致TCP连接丢失,我们的客户端是不会被告知的,这时候如果再进行数据收发操作就会产生异常。
所以,我们可以在初始化的时候声明一个isConnected
的Boolean变量;在connect()
函数中连接完成后赋值为true,并发送心跳包实时检测TCP连接是否丢失;在disconnect()
函数中赋值为false;在send()
和receive(size: Int)
中加入检测是否已连接的代码,如果未连接则不执行操作。
以下为一个简易的心跳包代码:
1 2 3 4 5 6 7 8 9 10 11 12 13
| fun heartbeat() { timer(period = 1000) { try { val value = receive() } catch (e: Exception) { if (isConnected) { isConnected = false disconnect() } cancel() } } }
|
在connect()
函数的最后调用heartbeat()
即可。
一次性获取服务器发过来的字符串
上面receive(size: Int)
函数指定了一次接收多少长度的数据。我们也可以改成用Scanner来一次性读取整行数据。
在初始化那里,把reader改成:
在connect()
函数里,把reader改成:
1
| reader = Scanner(InputStreamReader(socket.getInputStream()))
|
最后,把receive(size: Int)
函数改成下面这样即可:
1 2 3
| fun receive(): String { return reader.readText() }
|
完整代码
下面我把connect()
函数里面服务器的连接地址和端口改成了可以自定义的那种,并把整个TCP客户端封装成一个类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| import java.io.BufferedReader import java.io.InputStreamReader import java.io.PrintWriter import java.net.InetSocketAddress import java.net.Socket
class TCPConnect(private val serverIP: String, private val serverPort: Int) { private lateinit var socket: Socket private lateinit var reader: BufferedReader private lateinit var writer: PrintWriter var isConnected = false
fun connect() { socket = Socket() socket.connect(InetSocketAddress(serverIP, serverPort), 5000) reader = BufferedReader(InputStreamReader(socket.getInputStream())) writer = PrintWriter(socket.getOutputStream(), true) isConnected = true heartbeat() }
fun disconnect() { isConnected = false writer.close() reader.close() socket.close() }
fun send(message: String) { writer.println(message) }
fun receive(): String { val buffer = CharArray(24) val length = reader.read(buffer) return String(buffer, 0, length) }
fun heartbeat() { timer(period = 1000) { try { val value = receive() } catch (e: Exception) { if (isConnected) { isConnected = false disconnect() } cancel() } } } }
|
因为我TCP服务器的代码是用C语言提供的,这里就先不放出来了,以后有缘再用Kotlin写个这样简易的代码出来~