美文网首页
SwiftSocketSever

SwiftSocketSever

作者: br_MorningStar | 来源:发表于2017-11-25 13:23 被阅读185次
  • 接受消息
  • 转发消息
  • ProtocolBuffer

TCP/UDP的概念和区分

  • 进行Socket 编程,常见使用的协议UDP/TCP
    • TCP:传输控制协议,是专门设计用于在不可靠的因特尔网上提供可靠的,端到端的字节流通信的协议,他是一种面向连接的协议,TCP连接是字节流而非报文流
      • TCP 在传输数据是,传输的是字节流,在读取消息时,需要知道数据的长度,否则就会出现读取不完整或者读取过多的情况,因此读取方法要求发送方传入本次读取消息长度!


        图片.png
    • UDP: 用户数据报协议不需要连接,不可靠
  • 举例区分
    • TCP 类似于打电话,双方直接通信
    • UDP类似于发短信,双方发出消息后等待别人的回复
  • 建立连接时所需要的寻址信息为IP地址和端口号
    • IP地址: 用于区分那一台计算器需要和我建立连接
    • 端口号: 用于区分那一个应用程序和我建立连接

  • 消息类型
    • 结构体: 客户端把消息封装成结构体,转成Data类型->字节,发给服务器,(服务器解析出解析)服务器要是Java的话(因为不常用结构体!So...)
    • SOAP: XML描述,数据大
    • Json: 序列化,反序列化
    • ProtocolBuffer (PB,GPB)谷歌开源,跨平台,非常方便序列化,反序列化, 消息大小XML的20分之一,是二进制序列化的10分之一,Json的十分之一

  • BSD Socket 是UNIX系统中通用的网络接口!它不仅支持各种不同的网络类型,而且是一种内部进程之间的通信机制,iOS也可以用C语言函数
  • CFSock : 是苹果官方提供的Socket编程,里面还是有很多C语言,麻烦
  • AsyncSocket : 是开源的库OC版,用法很简单!两个文件.h.m
  • ysocket : 是Swift目前使用的Socket编程,SwiftSocket

图片.png
  1. cocoapods
 pod 'SwiftSocket'
 pod 'ProtocolBuffers-Swift'
  1. 创建SeverSocketManager文件管理Sever
  • import SwiftSocket
class SeverSocketManager {
    
    fileprivate var severSocket : TCPServer = TCPServer(address: "0.0.0.0", port: 5656)
    fileprivate var isSeverSocketRunning : Bool = false
    fileprivate lazy var clientManagerArray : [ClientManager] = [ClientManager]()

}
  • 开启方法 , 关闭
extension SeverSocketManager {
    func startSever() ->((String , Bool)){
         let flag = severSocket.listen()  //开启监听
        
        if flag.isSuccess {
            
            isSeverSocketRunning = true
            
            DispatchQueue.global().async {    //开启新线程
                while self.isSeverSocketRunning {    

                    if let client = self.severSocket.accept(){  //循环接受ClientSocket
                        
                        DispatchQueue.global().async {
                         self.handleClient(client)    //处理接收到的ClientSocket

                        }
                    }
                }
            }
            return ("开启成功",flag.isSuccess)
        }else{
            return ("开启失败",flag.isFailure)
        }

    }
    
    func stopSever(){
        isSeverSocketRunning = false
    }
}

  1. 处理ClientSocket
extension SeverSocketManager {
    fileprivate func handleClient (_ client : TCPClient){
        let mgr = ClientManager(tcpClient: client)
        mgr.delegate = self
        //保存客户端
        clientManagerArray.append(mgr)
        
        //用Client开始接受消息(读取消息)
        mgr.startRedMsg()
    }
}

extension SeverSocketManager : ClientManagerDelegate{
    
    func deleteClient(clientManager: ClientManager) {
        clientManager.tcpClient.close()
        guard let index = clientManagerArray.index(of: clientManager) else {return}
        clientManagerArray.remove(at: index)
        print(clientManagerArray.count)
    }
    
    func sendMsgClientTo(_ data: Data) {
        let str = String(data: data, encoding: .utf8)
        print(str!)
        for mgr in clientManagerArray{
            mgr.tcpClient.send(data: data)

        }
    }
}
  1. 创建ClientManager管理Client
  • import SwiftSocket
  • 创建代理用来给外界提供消息和移除断开连接的Client
protocol ClientManagerDelegate : class{
    func sendMsgClientTo(_ data : Data)
    func deleteClient(clientManager : ClientManager)
}
class ClientManager: NSObject {
    weak var delegate :  ClientManagerDelegate?
    var tcpClient : TCPClient
    fileprivate var isClientConnected : Bool = false    //连接状态
    fileprivate var heartTimeCount : Int = 0            //心跳包计时
    
    init(tcpClient : TCPClient) {
        self.tcpClient = tcpClient
    }
}
  • 读取消息函数
extension ClientManager{
    func startRedMsg(){
        
        //心跳包计时
        let timer = Timer(fireAt: Date(), interval: 1, target: self, selector: #selector(checkHeartBeat), userInfo: nil, repeats: true)
        RunLoop.current.add(timer, forMode: .commonModes)
        timer.fire()
        
        isClientConnected = true
        while isClientConnected {
            if let msg = tcpClient.read(4){    //读取4个字节
                //读取Header的长度
                let headerData = Data(bytes: msg, count: 4) //字节传承Data
                var length : Int = 0
                (headerData as NSData).getBytes(&length, length: 4)  //获取消息的长度
                
                //读取类型
                guard let messageType = tcpClient.read(2) else { return }
                let typeData = Data(bytes: messageType, count: 2)   //把类型转换成Data
                var type : Int = 0
                (typeData as NSData).getBytes(&type, length: 2)     //获取类型的长度
                //                print("type = \(type)")                             //获取类型
                
                //                print(length)
                //根据长度读取真正的消息
                guard let trueMsg = tcpClient.read(length) else { return }
                let data = Data(bytes: trueMsg, count: length)
                
                //1表示离开,断开连接
                if type == 1{    
                    DispatchQueue.main.async {
                        self.delegate?.deleteClient(clientManager: self)
                    }
                }
                else if type == 100{      //100消息类型(心跳包消息类型)
                    heartTimeCount = 0    //如果接收到心跳包则重置时间
                    let message = String(data: data, encoding: .utf8)
                    print(message!)
                    continue
                }

                //Data拼接转发
                let totalData = headerData + typeData + data
                delegate?.sendMsgClientTo(totalData)
                
            }else{
                removeClient()
            }
        }
    }
    @objc fileprivate func checkHeartBeat(){
        print("-------------")
        heartTimeCount += 1
        if heartTimeCount >= 10 {
            removeClient()
        }
    }
    
    fileprivate func removeClient(){
    
        isClientConnected = false
        print("客户端断开了链接")
        //从数组中删除ClientSocket
        delegate?.deleteClient(clientManager: self)
    }
}
  • 在OS 程序中
class ViewController: NSViewController {

    fileprivate lazy var severSocketManager : SeverSocketManager = SeverSocketManager()
    
    @IBOutlet weak var messageLabel: NSTextField!
    override func viewDidLoad() {
        super.viewDidLoad()

        
    }
    @IBAction func start(_ sender: NSButton) {
        let flag = severSocketManager.startSever()
        if flag.1{
            messageLabel.stringValue = "succeed"
            messageLabel.textColor = .green
        }else{
            messageLabel.stringValue = "fail"
            messageLabel.textColor = .red
        }
    }
    
    @IBAction func stop(_ sender: NSButton) {
        
    }
    
}```

相关文章

  • SwiftSocketSever

    接受消息转发消息ProtocolBuffer TCP/UDP的概念和区分 进行Socket 编程,常见使用的协议U...

网友评论

      本文标题:SwiftSocketSever

      本文链接:https://www.haomeiwen.com/subject/zchcbxtx.html