
Socket 就是對(duì)于傳輸層 TCP/IP 的封裝
簡(jiǎn)述:
由于最近項(xiàng)目的需要,需要使用到 Socket,所以就趁此整理了一下,網(wǎng)上對(duì)于 Socket 的理論知識(shí)有很多,這里就不必多說(shuō),此篇文章主要在 Swift 環(huán)境下使用 CocoaAsyncSocket 庫(kù),來(lái)實(shí)現(xiàn)一個(gè)非常簡(jiǎn)單的 Socket 連接的例子。
1.創(chuàng)建 Swift 工程,并使用 Cocoapods 導(dǎo)入 CocoaAsyncSocket

1.創(chuàng)建工程
Cocoapods:
use_frameworks!
pod 'CocoaAsyncSocket'
2.搭建服務(wù)端和客戶端 UI
使用 Tabbar 分別創(chuàng)建服務(wù)端界面和客戶端界面

3.服務(wù)端和客戶端的界面搭建
分別創(chuàng)建服務(wù)端和客戶端 ViewController 并關(guān)聯(lián)相關(guān) Textfield 和 Button
4.服務(wù)端創(chuàng)建 Socket 綁定端口,設(shè)置監(jiān)聽,消息發(fā)送等方法
ServerViewController




5.客戶端創(chuàng)建 Socket,設(shè)置連接,消息發(fā)送,讀取,斷開連接等方法
ClientViewController




import UIKit
import CocoaAsyncSocket
class ServerViewController:UIViewController{
? ? //端口
? ? @IBOutlet weak var portTF:UITextField!
? ? //消息
? ? @IBOutlet weak var msgTF:UITextField!
? ? //信息顯示
? ? @IBOutlet weak var infoTV:UITextView!
? ? var serverSocket:GCDAsyncSocket?
? ? var clientSocket:GCDAsyncSocket?
? ? override func viewDidLoad() {
? ? super.viewDidLoad()
? ? addText(text:"顯示檢測(cè)(服務(wù)端)")
}
//對(duì)InfoTextView添加提示內(nèi)容
func addText(text:String) {
? ? infoTV.text=infoTV.text.appendingFormat("%@\n", text)
}
//監(jiān)聽
@IBAction func listeningAct(_sender:Any) {
? ? serverSocket = GCDAsyncSocket(delegate:self, delegateQueue:DispatchQueue.main)
? ? do{
? ? ? ? try serverSocket?.accept(onPort:UInt16(portTF.text!)!)
? ? ? ? ? ? addText(text:"監(jiān)聽成功")
? ? }
? ? catch_{
? ? ? ? addText(text:"監(jiān)聽失敗")
? ? }
}
//發(fā)送
@IBAction func sendAct(_sender:Any) {
? ? let data = msgTF.text?.data(using:String.Encoding.utf8)
? ? //向客戶端寫入信息Timeout設(shè)置為-1則不會(huì)超時(shí), tag作為兩邊一樣的標(biāo)示
? ? clientSocket?.write(data!, withTimeout:-1, tag:0)
}
extension ServerViewController:GCDAsyncSocketDelegate {
? ? //當(dāng)接收到新的Socket連接時(shí)執(zhí)行
? ? func socket(_sock:GCDAsyncSocket, didAcceptNewSocket newSocket:GCDAsyncSocket) {
? ? ? ? addText(text:"連接成功")
? ? ? ? addText(text:"連接地址"+ newSocket.connectedHost!)
? ? ? ? addText(text:"端口號(hào)"+String(newSocket.connectedPort))
? ? ? ? clientSocket = newSocket
? ? ? ? //第一次開始讀取Data
? ? ? ? clientSocket!.readData(withTimeout:-1, tag:0)
? ? }
? ? func socket(_sock:GCDAsyncSocket, didRead data:Data, withTag tag:Int) {
? ? ? ? let message = String(data: data,encoding:String.Encoding.utf8)
? ? ? ? addText(text: message!)
? ? ? ? //再次準(zhǔn)備讀取Data,以此來(lái)循環(huán)讀取Data
? ? ? ? sock.readData(withTimeout:-1, tag:0)
? ? }
}
import UIKit
import CocoaAsyncSocket
class ClientViewController:UIViewController{
? ? // IP地址
? ? @IBOutlet weak var ipTF:UITextField!
? ? //端口
? ? @IBOutlet weak var portTF:UITextField!
? ? //消息
? ? @IBOutlet weak var msgTF:UITextField!
? ? //消息顯示
? ? @IBOutlet weak var infoTV:UITextView!
? ? var socket:GCDAsyncSocket?
? ? override func viewDidLoad() {
? ? ? ? super.viewDidLoad()
? ? ? ? addText(text:"顯示檢測(cè)(客戶端)")
? ? }
? ? func addText(text:String) {
? ? ? ? infoTV.text=infoTV.text.appendingFormat("%@\n", text)
? ? }
? ? //連接
? ? @IBAction func connectionAct(_sender:Any) {
? ? ? ? socket = GCDAsyncSocket(delegate:self, delegateQueue:DispatchQueue.main)
? ? ? ? do{
? ? ? ? ? ? try socket?.connect(toHost: ipTF.text!, onPort:UInt16(portTF.text!)!)
? ? ? ? ? ? ? ? addText(text:"連接成功")
? ? ? ? ? ? }
? ? ? ? catch_{
? ? ? ? ? ? addText(text:"連接失敗")
? ? ? ? }
? ? }
? ? //斷開
? ? @IBAction func disconnectAct(_sender:Any) {
? ? ? ? socket?.disconnect()
? ? ? ? addText(text:"斷開連接")
? ? }
? ? //發(fā)送
? ? @IBAction func sendMsgAct(_sender:Any) {
? ? ? ? socket?.write((msgTF.text?.data(using:String.Encoding.utf8))!, withTimeout:-1, tag:0)
? ? }
}
extension ClientViewController:GCDAsyncSocketDelegate {
? ? func socket(_sock:GCDAsyncSocket, didConnectToHost host:String, port:UInt16) {
? ? ? ? addText(text:"連接服務(wù)器"+host)
? ? ? ? self.socket?.readData(withTimeout:-1, tag:0)
? ? }
? ? func socket(_sock:GCDAsyncSocket, didRead data:Data, withTag tag:Int) {
? ? ? ? letmsg = String(data: dataasData, encoding:String.Encoding.utf8)
? ? ? ? addText(text: msg!)
? ? ? ? socket?.readData(withTimeout:-1, tag:0)
? ? }
}