简述:
- 由于最近项目的需要,需要使用到Socket,所以就趁此整理了一下,网上对于Socket的理论知识有很多,这里就不必多说,此篇文章主要在Swift环境下使用CocoaAsyncSocket库,来实现一个非常简单的Socket连接的例子,帮助大家理解和使用.(大神勿喷呀,哈哈)
1.创建Swift工程,并使用Cocoapods导入CocoaAsyncSocket
Cocoapods:
1 | use_frameworks! |
2.搭建服务端和客户端UI
使用Tabbar分别创建服务端界面和客户端界面
分别创建服务端和客户端ViewController并关联相关Textfield 和 Button
3.服务端创建Socket绑定端口,设置监听,消息发送等方法
- ServerViewController
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80//
// ServerViewController.swift
// TestSocket
//
// Created by YYQ on 6/21/16.
// Copyright © 2016 YYQ. All rights reserved.
//
import UIKit
import CocoaAsyncSocket
class ServerViewController: UIViewController {
//端口
weak var portTF: UITextField!
//消息
weak var msgTF: UITextField!
//信息显示
weak var infoTV: UITextView!
//服务端和客户端的socket引用
var serverSocket: GCDAsyncSocket?
var clientSocket: GCDAsyncSocket?
override func viewDidLoad() {
super.viewDidLoad()
}
//对InfoTextView添加提示内容
func addText(text: String) {
infoTV.text = infoTV.text.stringByAppendingFormat("%@\n", text)
}
///监听
func listeningAct(sender: AnyObject) {
serverSocket = GCDAsyncSocket(delegate: self, delegateQueue: dispatch_get_main_queue())
do {
try serverSocket?.acceptOnPort(UInt16(portTF.text!)!)
addText("监听成功")
}catch _ {
addText("监听失败")
}
}
///发送
func sendAct(sender: AnyObject) {
let data = msgTF.text?.dataUsingEncoding(NSUTF8StringEncoding)
//向客户端写入信息 Timeout设置为 -1 则不会超时, tag作为两边一样的标示
clientSocket?.writeData(data, withTimeout: -1, tag: 0)
}
}
extension ServerViewController: GCDAsyncSocketDelegate {
//当接收到新的Socket连接时执行
func socket(sock: GCDAsyncSocket!, didAcceptNewSocket newSocket: GCDAsyncSocket!) {
addText("连接成功")
addText("连接地址" + newSocket.connectedHost)
addText("端口号" + String(newSocket.connectedPort))
clientSocket = newSocket
//第一次开始读取Data
clientSocket!.readDataWithTimeout(-1, tag: 0)
}
func socket(sock: GCDAsyncSocket!, didReadData data: NSData!, withTag tag: Int) {
let message = String(data: data,encoding: NSUTF8StringEncoding)
addText(message!)
//再次准备读取Data,以此来循环读取Data
sock.readDataWithTimeout(-1, tag: 0)
}
}
4.客户端创建Socket,设置连接,消息发送,读取,断开连接等方法
- ClientViewController
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75//
// ClientViewController.swift
// TestSocket
//
// Created by YYQ on 6/21/16.
// Copyright 2016 YYQ. All rights reserved.
//
import UIKit
import CocoaAsyncSocket
class ClientViewController: UIViewController {
//IP地址
weak var ipTF: UITextField!
//端口
weak var portTF: UITextField!
//消息
weak var msgTF: UITextField!
//信息显示
weak var infoTV: UITextView!
var socket: GCDAsyncSocket?
override func viewDidLoad() {
super.viewDidLoad()
}
func addText(text: String) {
infoTV.text = infoTV.text.stringByAppendingFormat("%@\n", text)
}
//连接
func connectionAct(sender: AnyObject) {
socket = GCDAsyncSocket(delegate: self, delegateQueue: dispatch_get_main_queue())
do {
try socket?.connectToHost(ipTF.text, onPort: UInt16(portTF.text!)!)
addText("连接成功")
}catch _ {
addText("连接失败")
}
}
//断开
func disconnectAct(sender: AnyObject) {
socket?.disconnect()
addText("断开连接")
}
//发送
func sendMsgAct(sender: AnyObject) {
socket?.writeData(msgTF.text?.dataUsingEncoding(NSUTF8StringEncoding), withTimeout: -1, tag: 0)
}
}
extension ClientViewController: GCDAsyncSocketDelegate {
func socket(sock: GCDAsyncSocket!, didConnectToHost host: String!, port: UInt16) {
addText("连接服务器" + host)
self.socket?.readDataWithTimeout(-1, tag: 0)
}
func socket(sock: GCDAsyncSocket!, didReadData data: NSData!, withTag tag: Int) {
let msg = String(data: data, encoding: NSUTF8StringEncoding)
addText(msg!)
socket?.readDataWithTimeout(-1, tag: 0)
}
}
|服务端| 客户端 |
|—–|:—-:|—-|
|||
结语:
CocoaAsyncSocket的使用还是非常直观清晰的,这里只是简单的抛砖引玉,要更深入理解Socket,如果有时间的话,我觉得还是研究下底层的socket实现比较好,大家有什么问题欢迎提出来,一起共勉~
联系方式:yueyeqi@iCloud.com