Ios Swift:使用GCDAsyncUdpSocket接收UDP
背景: 我希望能够在iOS应用程序和服务器之间发送和接收UDP数据包。 服务器会将每个传入的消息回显到应用程序的客户端服务器经过测试并确认正常工作。我有一个StartViewController,它启动了两个实现GCDAsyncUdpSocketDelegate的类,一个用于发送,一个用于接收。“发送套接字”正在工作,服务器接收消息 问题: 该应用程序在发送传入消息后从未将其取回。侦听套接字设置可能有问题,因为从未调用过didReceiveData 我完全做错了吗 开始:Ios Swift:使用GCDAsyncUdpSocket接收UDP,ios,swift,udp,cocoaasyncsocket,gcdasyncudpsocket,Ios,Swift,Udp,Cocoaasyncsocket,Gcdasyncudpsocket,背景: 我希望能够在iOS应用程序和服务器之间发送和接收UDP数据包。 服务器会将每个传入的消息回显到应用程序的客户端服务器经过测试并确认正常工作。我有一个StartViewController,它启动了两个实现GCDAsyncUdpSocketDelegate的类,一个用于发送,一个用于接收。“发送套接字”正在工作,服务器接收消息 问题: 该应用程序在发送传入消息后从未将其取回。侦听套接字设置可能有问题,因为从未调用过didReceiveData 我完全做错了吗 开始: class Start
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)");
}
}
发送:
编辑:
添加了忘记的代码行。我终于让它与此套接字设置一起工作:
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)
}
Apple Swift 4.2.1版经过良好测试的UDP示例:- 步骤1:-
pod'CocoaAsyncSocket'
步骤2:-在UIViewController
中导入CocoaAsyncSocket
步骤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)
}
}
步骤4:-接收插座
步骤5:-发送套接字..
步骤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!
}
}
<代码>导入基础
结构信号{
var第一信号:UInt16=20
无功辅助信号:UInt16=30
第三个变量信号:UInt16=40
var第四信号:UInt16=50
静态函数存档(w:信号)->数据{
var fw=w
返回数据(字节:&fw,计数:MemoryLayout.stride)
}
静态函数未归档(d:数据)->信号{
guard d.count==MemoryLayout.stride{
法塔莱罗(“轰!”)
}
信号?
d、 withUnsafeBytes({(字节:UnsafePointer)->中的Void
s=未安全指针(字节)。指针对象
})
返回s!
}
}
您在InSocket中的socket属性的具体初始化位置。连接?,安东。谢谢注意。这是从我的项目代码中复制/粘贴的错误,我刚刚添加了它。但这不是问题所在,因为我的项目代码中存在套接字初始值。很抱歉重新打开一个旧线程,但我正在尝试将您的示例转换为Swift 2.1的函数,我不太清楚您在回答中引用的
服务器IP
真正指的是什么。我似乎在任何地方都找不到实例化的。很抱歉没有更清楚地说明这一点,服务器IP是一个字符串。谢谢@rilar。如果你愿意分享的话,我真的很想看到更多修改后的代码。我不清楚这个答案中的setupConnection()
是否是InSocket或OutSocket类的一部分,或者服务器IP的具体实例化位置。我花了很长时间寻找发送UDP数据的解决方案。这对我有帮助,谢谢!。现在我想知道如何从服务器上读取答案。有一个outSocket.response()方法,但我不知道如何使用它!有人能帮我吗。我看到服务器正在通过WireShark进行应答,但在我的应用程序中没有收到。fatalError(“BOOM!”)为什么?@DmitrySelesnashenko这是为了检查信号数据是否不存在,我们可以通过fatalError在这里捕获此问题。这非常重要:当您仅接收时,请不要尝试套接字。连接(到主机:IP,onPort:PORT)
。只有socket.bind(toPort:PORT)
才能启动接收。谢谢:)谢谢@marc_s让我们的社区变得更加美丽和可读
//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 proceed")}
do { try socket.beginReceiving()} catch { print("beginReceiving not proceed")}
}
//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?) {
}
}
//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 proceed")}
do { try socket.beginReceiving()} catch { print("beginReceiving not proceed")}
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")
}
}
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!
}
}