Swift - 使用socket进行通信(附聊天室样例)
在Swift开发中,如果我们需要保持客服端和服务器的长连接进行双向的数据通信,使用socket是一种很好的解决方案。
建消息体的时候使用字典NSDictionary(其中cmd表示命令类型,content表示内容体),发送消息时把字典转成json串传递,当另一端
接收的时候,又把json串还原成字典再执行响应的动作。
 
    
| 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 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | importUIKitclassViewController: UIViewController{        //消息输入框    @IBOutletweakvartextFiled: UITextField!    //消息输出列表    @IBOutletweakvartextView: UITextView!        //socket服务端封装类对象    varsocketServer:MyTcpSocketServer?    //socket客户端类对象    varsocketClient:TCPClient?        overridefuncviewDidLoad() {        super.viewDidLoad()                //启动服务器        socketServer = MyTcpSocketServer()        socketServer?.start()                //初始化客户端,并连接服务器        processClientSocket()    }        //初始化客户端,并连接服务器    funcprocessClientSocket(){        socketClient=TCPClient(addr: "localhost", port: 8080)        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), {            () -> Voidin                        //用于读取并解析服务端发来的消息            funcreadmsg()->NSDictionary?{                //read 4 byte int as type                ifletdata=self.socketClient!.read(4){                    ifdata.count==4{                        varndata=NSData(bytes: data, length: data.count)                        varlen:Int32=0                        ndata.getBytes(&len, length: data.count)                        ifletbuff=self.socketClient!.read(Int(len)){                            varmsgd:NSData=NSData(bytes: buff, length: buff.count)                            varmsgi:NSDictionary=NSJSONSerialization.JSONObjectWithData(                                msgd,                                options: .MutableContainers, error: nil) as! NSDictionary                            returnmsgi                        }                    }                }                returnnil            }                        //连接服务器            var(success,msg)=self.socketClient!.connect(timeout: 5)            ifsuccess{                dispatch_async(dispatch_get_main_queue(), {                    self.alert("connect success", after: {                    })                })                                //发送用户名给服务器(这里使用随机生成的)                varmsgtosend=["cmd":"nickname","nickname":"游客\(Int(arc4random()%1000))"]                self.sendMessage(msgtosend)                                //不断接收服务器发来的消息                whiletrue{                    ifletmsg=readmsg(){                        dispatch_async(dispatch_get_main_queue(), {                            self.processMessage(msg)                        })                    }else{                        dispatch_async(dispatch_get_main_queue(), {                            //self.disconnect()                        })                        break                    }                }            }else{                dispatch_async(dispatch_get_main_queue(), {                    self.alert(msg,after: {                    })                })            }        })    }        //“发送消息”按钮点击    @IBActionfuncsendMsg(sender: AnyObject) {        varcontent=textFiled.text        varmessage=["cmd":"msg","content":content]        self.sendMessage(message)        textFiled.text=nil    }        //发送消息    funcsendMessage(msgtosend:NSDictionary){        varmsgdata=NSJSONSerialization.dataWithJSONObject(msgtosend,            options: NSJSONWritingOptions.PrettyPrinted, error: nil)        varlen:Int32=Int32(msgdata!.length)        vardata:NSMutableData=NSMutableData(bytes: &len, length: 4)        self.socketClient!.send(data: data)        self.socketClient!.send(data:msgdata!)    }        //处理服务器返回的消息    funcprocessMessage(msg:NSDictionary){        varcmd:String=msg["cmd"] as! String        switch(cmd){        case"msg":            self.textView.text = self.textView.text +                (msg["from"] as! String) + ": "+ (msg["content"] as! String) + "\n"        default:            println(msg)        }    }        //弹出消息框    funcalert(msg:String,after:()->(Void)){        varalertview=UIAlertView(title: "", message: msg, delegate: nil,            cancelButtonTitle: nil)        alertview.show()        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 3), dispatch_get_main_queue(),{            alertview.dismissWithClickedButtonIndex(0, animated: true)            after()        })    }        overridefuncdidReceiveMemoryWarning() {        super.didReceiveMemoryWarning()    }} | 
| 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 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | importUIKit//服务器端口varserverport = 8080//客户端管理类(便于服务端管理所有连接的客户端)classChatUser:NSObject{    vartcpClient:TCPClient?    varusername:String=""    varsocketServer:MyTcpSocketServer?        //解析收到的消息    funcreadMsg()->NSDictionary?{        //read 4 byte int as type        ifletdata=self.tcpClient!.read(4){            ifdata.count==4{                varndata=NSData(bytes: data, length: data.count)                varlen:Int32=0                ndata.getBytes(&len, length: data.count)                ifletbuff=self.tcpClient!.read(Int(len)){                    varmsgd:NSData=NSData(bytes: buff, length: buff.count)                    varmsgi:NSDictionary=NSJSONSerialization.JSONObjectWithData(msgd,                        options: .MutableContainers, error: nil) as! NSDictionary                    returnmsgi                }            }        }        returnnil    }        //循环接收消息    funcmessageloop(){        whiletrue{            ifletmsg=self.readMsg(){                self.processMsg(msg)            }else{                self.removeme()                break            }        }    }        //处理收到的消息    funcprocessMsg(msg:NSDictionary){        ifmsg["cmd"] as! String=="nickname"{            self.username=msg["nickname"] as! String        }        self.socketServer!.processUserMsg(user: self, msg: msg)    }        //发送消息    funcsendMsg(msg:NSDictionary){        varjsondata=NSJSONSerialization.dataWithJSONObject(msg, options:            NSJSONWritingOptions.PrettyPrinted, error: nil)        varlen:Int32=Int32(jsondata!.length)        vardata:NSMutableData=NSMutableData(bytes: &len, length: 4)        self.tcpClient!.send(data: data)        self.tcpClient!.send(data: jsondata!)    }        //移除该客户端    funcremoveme(){        self.socketServer!.removeUser(self)    }        //关闭连接    funckill(){        self.tcpClient!.close()    }}//服务端类classMyTcpSocketServer: NSObject{    varclients:[ChatUser]=[]    varserver:TCPServer=TCPServer(addr: "127.0.0.1", port: serverport)    varserverRuning:Bool=false        //启动服务    funcstart() {        server.listen()        self.serverRuning=true        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), {            whileself.serverRuning{                varclient=self.server.accept()                ifletc=client{                    dispatch_async(                        dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), {                        self.handleClient(c)                    })                }            }        })        self.log("server started...")    }        //停止服务    funcstop() {        self.serverRuning=false        self.server.close()        //forth close all client socket        forc:ChatUserinself.clients{            c.kill()        }        self.log("server stoped...")    }    //处理连接的客户端    funchandleClient(c:TCPClient){        self.log("new client from:"+c.addr)        varu=ChatUser()        u.tcpClient=c        clients.append(u)        u.socketServer=self        u.messageloop()    }        //处理各消息命令    funcprocessUserMsg(user u:ChatUser,msg m:NSDictionary){        self.log("\(u.username)[\(u.tcpClient!.addr)]cmd:"+(m["cmd"] as! String))        //boardcast message        varmsgtosend=[String:String]()        varcmd = m["cmd"] as! String        ifcmd=="nickname"{            msgtosend["cmd"]="join"            msgtosend["nickname"]=u.username            msgtosend["addr"]=u.tcpClient!.addr        }elseif(cmd=="msg"){            msgtosend["cmd"]="msg"            msgtosend["from"]=u.username            msgtosend["content"]=(m["content"] as! String)        }elseif(cmd=="leave"){            msgtosend["cmd"]="leave"            msgtosend["nickname"]=u.username            msgtosend["addr"]=u.tcpClient!.addr        }        foruser:ChatUserinself.clients{            //if u~=user{            user.sendMsg(msgtosend)            //}        }    }        //移除用户    funcremoveUser(u:ChatUser){        self.log("remove user\(u.tcpClient!.addr)")        ifletpossibleIndex=find(self.clients, u){            self.clients.removeAtIndex(possibleIndex)            self.processUserMsg(user: u, msg: ["cmd":"leave"])        }    }        //日志打印    funclog(msg:String){        println(msg)    }} | 
源码下载: SocketTest.zip
SocketTest.zip
Swift - 使用socket进行通信(附聊天室样例)的更多相关文章
- 第四节:SignalR灵魂所在Hub模型及再探聊天室样例
		一. 整体介绍 本节:开始介绍SignalR另外一种通讯模型Hub(中心模型,或者叫集线器模型),它是一种RPC模式,允许客户端和服务器端各自自定义方法并且相互调用,对开发者来说相当友好. 该节包括的 ... 
- Ext JS学习第十六天 事件机制event(一)  DotNet进阶系列(持续更新)  第一节:.Net版基于WebSocket的聊天室样例  第十五节:深入理解async和await的作用及各种适用场景和用法  第十五节:深入理解async和await的作用及各种适用场景和用法  前端自动化准备和详细配置(NVM、NPM/CNPM、NodeJs、NRM、WebPack、Gulp/Grunt、G
		code&monkey Ext JS学习第十六天 事件机制event(一) 此文用来记录学习笔记: 休息了好几天,从今天开始继续保持更新,鞭策自己学习 今天我们来说一说什么是事件,对于事件 ... 
- 第一节:.Net版基于WebSocket的聊天室样例
		一. 说在前面的话 该篇文章为实时通讯系列的第一节,基于WebSocket编写了一个简易版聊天样例,主要作用是为引出后面SignalR系列的用法及其强大方便之处,通过这个样例与后续的SignalR对比 ... 
- Express+Socket.IO 实现简易聊天室
		代码地址如下:http://www.demodashi.com/demo/12477.html 闲暇之余研究了一下 Socket.io,搭建了一个简易版的聊天室,如有不对之处还望指正,先上效果图: 首 ... 
- 示例:Socket应用之简易聊天室
		在实际应用中,Server总是在指定的端口上监听是否有Client请求,一旦监听到Client请求,Server就会启动一个线程来响应该请求,而Server本身在启动完线程之后马上又进入监听状态. 示 ... 
- 【Java】Socket+多线程实现控制台聊天室
		转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/5827212.html 聊天室程序的结构图: 架构解释: Server服务器相当于一个中转站,Client客户端 ... 
- 使用socket.io打造公共聊天室
		最近的计算机网络课上老师开始讲socket,tcp相关的知识,当时脑袋里就蹦出一个想法,那就是打造一个聊天室.实现方式也挺多的,常见的可以用C++或者Java进行socket编程来构建这么一个聊天室. ... 
- 利用socket.io构建一个聊天室
		利用socket.io来构建一个聊天室,输入自己的id和消息,所有的访问用户都可以看到,类似于群聊. socket.io 这里只用来做一个简单的聊天室,官网也有例子,很容易就做出来了.其实主要用的东西 ... 
- C#编程 socket编程之unity聊天室
		上面我们创建了tcp的客户端和服务端,但是只能进行消息的一次收发.这次我们做一个unity的简易聊天室,使用了线程,可以使用多个客户端连接服务器,并且一个客户端给服务器发消息后,服务器会将消息群发给所 ... 
随机推荐
- if语句之有房么?有钱么?有能力么?
			思路:1.如果有房,可以谈谈 2.如果没有房,问第二个条件有钱么,如果有,可以谈谈 3.如果没有房没有钱,则问第三个条件有能力么,如果有,可以谈谈 4.如果以上三个条件都没有,则拜拜 Console. ... 
- 利用 操作符特性  代替if判断语句
			参考:http://blog.csdn.net/speedme/article/details/22916181 1.&&的判断特性 #include <stdio.h> ... 
- 各国iPhone5系列最新裸机价格
			美国/加拿大/中国香港/中国大陆iPhone5系列最新裸机价格 
- android 从服务器上获取APK并下载安装
			简单的为新手做个分享. 网上有些资料,不过都是很零散,或是很乱的,有的人说看不懂. 一直有新手说 做到服务器更新APK时没有思路,这里做个简单的分享,希望有不同思路的可以讨论. 下 ... 
- 基于端口的VLAN典型配置指导
			本文为转发,简单明了,我喜欢 VLAN典型配置全过程如下: 组网图 图1-1 基于端口的VLAN组网示意图 应用要求 如图1-1所示,Switch A和Switch B分别连接了不同部门使用的Host ... 
- C++多态原理
			C++的多态性是通过动态绑定实现的 非虚函数是在编译时绑定的; 通过对象进行的函数(虚函数,非虚函数)也是编译时绑定的; C++编译器在编译的时候,要确定每个对象调用的函数(要求此函数是非虚函数)的地 ... 
- 《Python爬虫学习系列教程》学习笔记
			http://cuiqingcai.com/1052.html 大家好哈,我呢最近在学习Python爬虫,感觉非常有意思,真的让生活可以方便很多.学习过程中我把一些学习的笔记总结下来,还记录了一些自己 ... 
- [置顶] 正则表达式应用:匹配email地址
			email的组成主要有三部分 1用户名部分 2@ 3域名部分 1用户名部分 用户名一般有数值字母下划线组成,所以正则表达式为:[\da- ... 
- 基于visual Studio2013解决C语言竞赛题之1002字符打印
			    题目 解决代码及点评 /************************************************************************/ /* ... 
- Android应用之基本的组件(一)
			请大家伙多多指教: 邮箱:weimingweicom@sina.com 请关注:ailiandeziwei 总的页面: 注意:按钮间方法的改变需要: android:onClick=" ... 
