背景:
我希望能够在我的iOS应用和服务器之间发送和接收UDP数据包。 服务器将每个传入的消息回送给应用程序的客户端。 服务器经过测试并确认正常运行。我有一个StartViewController,启动两个实现GCDAsyncUdpSocketDelegate的类,一个用于发送,一个用于接收。 "发送套接字"正在运行,服务器接收消息。
问题:
应用程序在发送后永远不会收到回传消息。听取套接字设置的东西可能是错误的,因为didReceiveData永远不会被调用。
我完全错了吗?
开始:
class StartViewController: UIViewController {
var inSocket : InSocket!
var outSocket : OutSocket!
override func viewDidLoad() {
super.viewDidLoad()
inSocket = InSocket()
outSocket = OutSocket()
}
@IBAction func goButton(sender: UIButton) {
outSocket.send("This is a message!")
}
}
接收:
class InSocket: NSObject, GCDAsyncUdpSocketDelegate {
let IP = "255.255.255.255"
let PORT:UInt16 = 5556
var socket:GCDAsyncUdpSocket!
override init(){
super.init()
setupConnection()
}
func setupConnection(){
var error : NSError?
socket = GCDAsyncUdpSocket(delegate: self, delegateQueue: dispatch_get_main_queue())
socket.bindToPort(PORT, error: &error)
socket.enableBroadcast(true, error: &error)
socket.joinMulticastGroup(IP, error: &error)
socket.beginReceiving(&error)
}
func udpSocket(sock: GCDAsyncUdpSocket!, didReceiveData data: NSData!, fromAddress address: NSData!, withFilterContext filterContext: AnyObject!) {
println("incoming message: \(data)");
}
}
发送:
class OutSocket: NSObject, GCDAsyncUdpSocketDelegate {
let IP = "90.112.76.180"
let PORT:UInt16 = 5556
var socket:GCDAsyncUdpSocket!
override init(){
super.init()
setupConnection()
}
func setupConnection(){
var error : NSError?
socket = GCDAsyncUdpSocket(delegate: self, delegateQueue: dispatch_get_main_queue())
socket.connectToHost(IP, onPort: PORT, error: &error)
}
func send(message:String){
let data = message.dataUsingEncoding(NSUTF8StringEncoding)
socket.sendData(data, withTimeout: 2, tag: 0)
}
func udpSocket(sock: GCDAsyncUdpSocket!, didConnectToAddress address: NSData!) {
println("didConnectToAddress");
}
func udpSocket(sock: GCDAsyncUdpSocket!, didNotConnect error: NSError!) {
println("didNotConnect \(error)")
}
func udpSocket(sock: GCDAsyncUdpSocket!, didSendDataWithTag tag: Int) {
println("didSendDataWithTag")
}
func udpSocket(sock: GCDAsyncUdpSocket!, didNotSendDataWithTag tag: Int, dueToError error: NSError!) {
println("didNotSendDataWithTag")
}
}
修改 添加了遗忘的代码行。
答案 0 :(得分:12)
我终于使用了这个套接字设置:
func setupConnection(){
var error : NSError?
socket = GCDAsyncUdpSocket(delegate: self, delegateQueue: dispatch_get_main_queue())
socket.bindToPort(PORT, error: &error)
socket.connectToHost(SERVER_IP, onPort: PORT, error: &error)
socket.beginReceiving(&error)
send("ping")
}
func send(message:String){
let data = message.dataUsingEncoding(NSUTF8StringEncoding)
socket.sendData(data, withTimeout: 2, tag: 0)
}
答案 1 :(得分:1)
Apple Swift版本4.2.1经过良好测试的UDP示例:-
步骤1:-pod 'CocoaAsyncSocket'
第2步:-import CocoaAsyncSocket
中的UIViewController
。
步骤3:-UIViewController
import UIKit
import CocoaAsyncSocket
class ViewController: UIViewController {
@IBOutlet weak var btnOnOff: LightButton!
@IBOutlet weak var lblStatus: UILabel!
var inSocket : InSocket!
var outSocket : OutSocket!
override func viewDidLoad() {
super.viewDidLoad()
lblStatus.isHidden = true
inSocket = InSocket()
outSocket = OutSocket()
outSocket.setupConnection {
self.lblStatus.isHidden = false
}
}
@IBAction func btnLight(_ sender: Any) {
let signal:Signal = Signal()
self.outSocket.send(signal: signal)
}
}
STEP 4:- 接收套接字
//Reciving End...
class InSocket: NSObject, GCDAsyncUdpSocketDelegate {
//let IP = "10.123.45.2"
let IP = "127.0.0.1"
let PORT:UInt16 = 5001
var socket:GCDAsyncUdpSocket!
override init(){
super.init()
setupConnection()
}
func setupConnection(){
socket = GCDAsyncUdpSocket(delegate: self, delegateQueue:DispatchQueue.main)
do { try socket.bind(toPort: PORT)} catch { print("")}
do { try socket.enableBroadcast(true)} catch { print("not able to brad cast")}
do { try socket.joinMulticastGroup(IP)} catch { print("joinMulticastGroup not procceed")}
do { try socket.beginReceiving()} catch { print("beginReceiving not procceed")}
}
//MARK:-GCDAsyncUdpSocketDelegate
func udpSocket(_ sock: GCDAsyncUdpSocket, didReceive data: Data, fromAddress address: Data, withFilterContext filterContext: Any?) {
print("incoming message: \(data)");
let signal:Signal = Signal.unarchive(d: data)
print("signal information : \n first \(signal.firstSignal) , second \(signal.secondSignal) \n third \(signal.thirdSignal) , fourth \(signal.fourthSignal)")
}
func udpSocket(_ sock: GCDAsyncUdpSocket, didNotConnect error: Error?) {
}
func udpSocketDidClose(_ sock: GCDAsyncUdpSocket, withError error: Error?) {
}
}
STEP 5:- 正在发送套接字。
//Sending End...
class OutSocket: NSObject, GCDAsyncUdpSocketDelegate {
// let IP = "10.123.45.1"
let IP = "127.0.0.1"
let PORT:UInt16 = 5001
var socket:GCDAsyncUdpSocket!
override init(){
super.init()
}
func setupConnection(success:(()->())){
socket = GCDAsyncUdpSocket(delegate: self, delegateQueue:DispatchQueue.main)
do { try socket.bind(toPort: PORT)} catch { print("")}
do { try socket.connect(toHost:IP, onPort: PORT)} catch { print("joinMulticastGroup not procceed")}
do { try socket.beginReceiving()} catch { print("beginReceiving not procceed")}
success()
}
func send(signal:Signal){
let signalData = Signal.archive(w: signal)
socket.send(signalData, withTimeout: 2, tag: 0)
}
//MARK:- GCDAsyncUdpSocketDelegate
func udpSocket(_ sock: GCDAsyncUdpSocket, didConnectToAddress address: Data) {
print("didConnectToAddress");
}
func udpSocket(_ sock: GCDAsyncUdpSocket, didNotConnect error: Error?) {
if let _error = error {
print("didNotConnect \(_error )")
}
}
func udpSocket(_ sock: GCDAsyncUdpSocket, didNotSendDataWithTag tag: Int, dueToError error: Error?) {
print("didNotSendDataWithTag")
}
func udpSocket(_ sock: GCDAsyncUdpSocket, didSendDataWithTag tag: Int) {
print("didSendDataWithTag")
}
}
第6步:-您的信号数据,您将发送/接收
import Foundation
struct Signal {
var firstSignal:UInt16 = 20
var secondSignal:UInt16 = 30
var thirdSignal: UInt16 = 40
var fourthSignal: UInt16 = 50
static func archive(w:Signal) -> Data {
var fw = w
return Data(bytes: &fw, count: MemoryLayout<Signal>.stride)
}
static func unarchive(d:Data) -> Signal {
guard d.count == MemoryLayout<Signal>.stride else {
fatalError("BOOM!")
}
var s:Signal?
d.withUnsafeBytes({(bytes: UnsafePointer<Signal>)->Void in
s = UnsafePointer<Signal>(bytes).pointee
})
return s!
}
}