标签:
在Swift开发中,如果我们需要保持客服端和服务器的长连接进行双向的数据通信,使用socket是一种很好的解决方案。
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
|
import UIKit class ViewController : UIViewController { //消息输入框 @IBOutlet weak var textFiled: UITextField ! //消息输出列表 @IBOutlet weak var textView: UITextView ! //socket服务端封装类对象 var socketServer: MyTcpSocketServer ? //socket客户端类对象 var socketClient: TCPClient ? override func viewDidLoad() { super .viewDidLoad() //启动服务器 socketServer = MyTcpSocketServer () socketServer?.start() //初始化客户端,并连接服务器 processClientSocket() } //初始化客户端,并连接服务器 func processClientSocket(){ socketClient= TCPClient (addr: "localhost" , port: 8080) dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_BACKGROUND , 0), { () -> Void in //用于读取并解析服务端发来的消息 func readmsg()-> NSDictionary ?{ //read 4 byte int as type if let data= self .socketClient!.read(4){ if data.count==4{ var ndata= NSData (bytes: data, length: data.count) var len: Int32 =0 ndata.getBytes(&len, length: data.count) if let buff= self .socketClient!.read( Int (len)){ var msgd: NSData = NSData (bytes: buff, length: buff.count) var msgi: NSDictionary = NSJSONSerialization . JSONObjectWithData ( msgd, options: . MutableContainers , error: nil ) as ! NSDictionary return msgi } } } return nil } //连接服务器 var (success,msg)= self .socketClient!.connect(timeout: 5) if success{ dispatch_async(dispatch_get_main_queue(), { self .alert( "connect success" , after: { }) }) //发送用户名给服务器(这里使用随机生成的) var msgtosend=[ "cmd" : "nickname" , "nickname" : "游客\(Int(arc4random()%1000))" ] self .sendMessage(msgtosend) //不断接收服务器发来的消息 while true { if let msg=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: { }) }) } }) } //“发送消息”按钮点击 @IBAction func sendMsg(sender: AnyObject ) { var content=textFiled.text var message=[ "cmd" : "msg" , "content" :content] self .sendMessage(message) textFiled.text= nil } //发送消息 func sendMessage(msgtosend: NSDictionary ){ var msgdata= NSJSONSerialization .dataWithJSONObject(msgtosend, options: NSJSONWritingOptions . PrettyPrinted , error: nil ) var len: Int32 = Int32 (msgdata!.length) var data: NSMutableData = NSMutableData (bytes: &len, length: 4) self .socketClient!.send(data: data) self .socketClient!.send(data:msgdata!) } //处理服务器返回的消息 func processMessage(msg: NSDictionary ){ var cmd: 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) } } //弹出消息框 func alert(msg: String ,after:()->( Void )){ var alertview= 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() }) } override func didReceiveMemoryWarning() { 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
|
import UIKit //服务器端口 var serverport = 8080 //客户端管理类(便于服务端管理所有连接的客户端) class ChatUser : NSObject { var tcpClient: TCPClient ? var username: String = "" var socketServer: MyTcpSocketServer ? //解析收到的消息 func readMsg()-> NSDictionary ?{ //read 4 byte int as type if let data= self .tcpClient!.read(4){ if data.count==4{ var ndata= NSData (bytes: data, length: data.count) var len: Int32 =0 ndata.getBytes(&len, length: data.count) if let buff= self .tcpClient!.read( Int (len)){ var msgd: NSData = NSData (bytes: buff, length: buff.count) var msgi: NSDictionary = NSJSONSerialization . JSONObjectWithData (msgd, options: . MutableContainers , error: nil ) as ! NSDictionary return msgi } } } return nil } //循环接收消息 func messageloop(){ while true { if let msg= self .readMsg(){ self .processMsg(msg) } else { self .removeme() break } } } //处理收到的消息 func processMsg(msg: NSDictionary ){ if msg[ "cmd" ] as ! String == "nickname" { self .username=msg[ "nickname" ] as ! String } self .socketServer!.processUserMsg(user: self , msg: msg) } //发送消息 func sendMsg(msg: NSDictionary ){ var jsondata= NSJSONSerialization .dataWithJSONObject(msg, options: NSJSONWritingOptions . PrettyPrinted , error: nil ) var len: Int32 = Int32 (jsondata!.length) var data: NSMutableData = NSMutableData (bytes: &len, length: 4) self .tcpClient!.send(data: data) self .tcpClient!.send(data: jsondata!) } //移除该客户端 func removeme(){ self .socketServer!.removeUser( self ) } //关闭连接 func kill(){ self .tcpClient!.close() } } //服务端类 class MyTcpSocketServer : NSObject { var clients:[ ChatUser ]=[] var server: TCPServer = TCPServer (addr: "127.0.0.1" , port: serverport) var serverRuning: Bool = false //启动服务 func start() { server.listen() self .serverRuning= true dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_BACKGROUND , 0), { while self .serverRuning{ var client= self .server.accept() if let c=client{ dispatch_async( dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_BACKGROUND , 0), { self .handleClient(c) }) } } }) self .log( "server started..." ) } //停止服务 func stop() { self .serverRuning= false self .server.close() //forth close all client socket for c: ChatUser in self .clients{ c.kill() } self .log( "server stoped..." ) } //处理连接的客户端 func handleClient(c: TCPClient ){ self .log( "new client from:" +c.addr) var u= ChatUser () u.tcpClient=c clients.append(u) u.socketServer= self u.messageloop() } //处理各消息命令 func processUserMsg(user u: ChatUser ,msg m: NSDictionary ){ self .log( "\(u.username)[\(u.tcpClient!.addr)]cmd:" +(m[ "cmd" ] as ! String )) //boardcast message var msgtosend=[ String : String ]() var cmd = m[ "cmd" ] as ! String if cmd== "nickname" { msgtosend[ "cmd" ]= "join" msgtosend[ "nickname" ]=u.username msgtosend[ "addr" ]=u.tcpClient!.addr } else if (cmd== "msg" ){ msgtosend[ "cmd" ]= "msg" msgtosend[ "from" ]=u.username msgtosend[ "content" ]=(m[ "content" ] as ! String ) } else if (cmd== "leave" ){ msgtosend[ "cmd" ]= "leave" msgtosend[ "nickname" ]=u.username msgtosend[ "addr" ]=u.tcpClient!.addr } for user: ChatUser in self .clients{ //if u~=user{ user.sendMsg(msgtosend) //} } } //移除用户 func removeUser(u: ChatUser ){ self .log( "remove user\(u.tcpClient!.addr)" ) if let possibleIndex= find ( self .clients, u){ self .clients.removeAtIndex(possibleIndex) self .processUserMsg(user: u, msg: [ "cmd" : "leave" ]) } } //日志打印 func log(msg: String ){ println (msg) } } |
源码下载:SocketTest.zip
标签:
原文地址:http://www.cnblogs.com/Free-Thinker/p/4843325.html