如何快速制作 DatagramPacket 代码?

Posted

技术标签:

【中文标题】如何快速制作 DatagramPacket 代码?【英文标题】:How can I make DatagramPacket code on swift? 【发布时间】:2018-10-10 02:41:16 【问题描述】:

所以我有这个使用 DatagramPacket 发送和接收 udp 消息的 java(android) 代码。

DatagramSocket ds = null;
ds = new DatagramSocket();
            ds.setSoTimeout(30000);
            InetAddress serverAddr = InetAddress.getByName(IP_ADDRESS);
            DatagramPacket dp;
            dp = new DatagramPacket(udpMsg.getBytes(), udpMsg.length(), serverAddr, UDP_SERVER_PORT);

            ds.send(dp);

            byte[] receiveData = new byte[1024];
            DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
            ds.receive(receivePacket);
            response = new String(receivePacket.getData(), "UTF-8");

            String str = new String(receivePacket.getData(), "UTF-8");
            data1 = str.substring(0,receivePacket.getLength());


private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() 

        @Override
        public void onReceive(Context context, Intent intent) 
            String sender = intent.getStringExtra("sender");
            Bundle msg = intent.getBundleExtra("message");
        
    ;

LocalBroadcastManager.getInstance(context).registerReceiver(
                mMessageReceiver, new IntentFilter("UDPBroadcast"));

现在,我想在 ios 上做同样的事情。我目前有这个代码。

let manager = SocketManager(socketURL: URL(string: "http://\(host):\(connectPort)")!, config: [.log(true), .compress])
       let socket = manager.defaultSocket

       socket.on(clientEvent: .connect) data, ack in
           print("socket connected")
       

       socket.on("sender") data, ack in

           print("sender data: \(data)")
       

       socket.connect()

但它给了我这些日志

SocketIOClient/: Adding handler for event: connect
SocketIOClient/: Adding handler for event: sender
SocketIOClient/: Handling event: statusChange with data: [connecting]
SocketIOClient/: Joining namespace /
SocketManager: Tried connecting socket when engine isn't open. Connecting
SocketManager: Adding engine
SocketManager: Manager is being released
SocketIOClient/: Client is being released
SocketEngine: Starting engine. Server: http://255.255.255.255:6000
SocketEngine: Handshaking
SocketEnginePolling: Doing polling GET http://255.255.255.255:6000/socket.io/?transport=polling&b64=1
SocketEnginePolling: Could not connect to the server.
SocketEngine: Could not connect to the server.
SocketEngine: Engine is being released

我调用的服务器是一个 golang 服务器,它是自签名的。 android代码执行速度很快。我是 iOS 开发和套接字的新手。如果您可以推荐除 SocketIO 之外的其他可以进行套接字连接的 pod,请附上示例代码或链接到它。

更新: 这是我当前的代码

import Foundation
import CocoaAsyncSocket
import SocketIO
import Starscream

class UDPSocket: NSObject, GCDAsyncUdpSocketDelegate
    var udpSock : GCDAsyncUdpSocket!
    let listenPort: UInt16 = 6000
    let data = "test".data(using: String.Encoding.utf8)!
    let host = "255.255.255.255"
    let connectPort: UInt16 = 6000
    let manager = SocketManager(socketURL: URL(string: "http://255.255.255.255:6000")!, config: [.log(true), .compress])

    override init() 
        super.init()
        print("init")
        udpSock = GCDAsyncUdpSocket(delegate: self, delegateQueue: DispatchQueue.main)

        do
            try udpSock!.bind(toPort: listenPort)
            try udpSock!.enableBroadcast(true)
        catch _ as NSError 
            print("Issue with d to Port")
            return
        

        let socket = manager.defaultSocket

        socket.on(clientEvent: .connect) data, ack in
            print("socket connected")
        

        socket.on("sender") data, ack in

            print("sender data: \(data)")
        

        socket.connect()

    

    func sendUDP()
        do 
            try udpSock!.beginReceiving()
            udpSock.send(data, toHost: host, port: connectPort, withTimeout: 60, tag: 0)
        catch _ as NSError 
            print("Issue with sending to Port: ")
            return
        
    


    public func udpSocket(_ sock: GCDAsyncUdpSocket, didReceive data: Data, fromAddress address: Data, withFilterContext filterContext: Any?) 
        let str = NSString(data: data as Data, encoding: String.Encoding.utf8.rawValue)
        print("received: \(String(describing: str))")

        if let data1 = str?.intValue
            if(data1 > 0)
                print("data1 isNum: \(data1)")
            
        

    

    public func udpSocket(_ sock: GCDAsyncUdpSocket, didSendDataWithTag tag: Int) 

        print("didSendDataWithTag")
    

    public func udpSocket(_ sock: GCDAsyncUdpSocket, didNotSendDataWithTag tag: Int, dueToError  error: Error?) 

        print("didNOTSendDataWithTag err: \(String(describing: error))")
    

    public func udpSocket(_ sock: GCDAsyncUdpSocket, didNotConnect error: Error?) 
        print("didNOTConnect")
    

    public func udpSocketDidClose(_ sock: GCDAsyncUdpSocket, withError error: Error?) 
        print("DidCloseSocket")
    

    @objc  public func udpSocket(_ sock: GCDAsyncUdpSocket, didConnectToAddress address: Data) 
        let str = NSString(data: data as Data, encoding: String.Encoding.utf8.rawValue)
        print("didConnectToAddress addr: \(String(describing: str))")

    

【问题讨论】:

【参考方案1】:

您的SocketManager 似乎由于其本地范围而被释放。您应该创建管理器的全局对象。

喜欢

let manager = SocketManager(socketURL: URL(string: "http://localhost:8080")!, config: [.log(true)])

【讨论】:

但这和我在android版本上使用的是一样的 你必须在你的类下面创建SocketManager的全局对象 类似var socketManager: SocketManager()? let manager = SocketManager(socketURL: URL(string: "http://\(host):\(connectPort)")!, config: [.log(true), .compress]) 你明白我的意思吗? 我已经添加了我的代码。但我仍然无法连接到我的服务器【参考方案2】:

嗨@rminaj,这基本上就是我正在做的事情

class YourClass 

  var manager : SocketManager!
  var socket : SocketIOClient!

  func establishConnection() 
    self.manager = SocketManager(socketURL: yourUrl, config: [.log(true), .compress])
    self.socket = self.manager.defaultSocket
  

【讨论】:

在尝试您的代码后,错误现在显示 The Internet connection appears to be offline. 你认为我需要在 Info.plist 上配置一些东西,但我已经得到了 App Transport Security Settings 不确定。您能否以某种方式应用程序之外访问 URL,例如 ping $url 我无法 ping 该网址。但是,我可以在 android 上调用它【参考方案3】:

您正在使用SocketIO 客户端。它是一个用于WebSocket 协议的库,它已经超过了tcp

请改用SwiftSocket。

很简单

udpSocket = UDPClient(address: ADDR, port: PORT)

否则你可以使用GCDAsyncUdpSocketReference

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)

其他可能的答案:How to implement UDP client and send data in Swift on iPhone?

【讨论】:

我已经在使用GCDAsyncUdpSocket 并且已经得到了结果。但我仍然需要从套接字接收另一个数据。如果你看一下java代码,它是intent.getStringExtra("sender") 看来我搞混了。我想我需要使用NSNotificationCenter 来获取第二个值。

以上是关于如何快速制作 DatagramPacket 代码?的主要内容,如果未能解决你的问题,请参考以下文章

如何制作更好地访问数组的快速代码?

Java,DatagramPacket接收,如何判断本地ip接口

Java网络编程 - UDP通信

如何以编程方式快速制作 UIProgressBar

如何快速制作静音和取消静音按钮?

DatagramPacket - getData 是不是总是返回传递的相同缓冲区?