Retrieving a string from a UDP server message
Asked Answered
V

3

1

I'm using the CocoaAsyncSocket library in my Swift-based iOS app. I have created an async UDP socket to a UDP server on my network, and it sends back a reply.

I'm reading this reply like this:

func udpSocket(sock: GCDAsyncUdpSocket!, didReceiveData data: NSData!, fromAddress address: NSData!, withFilterContext filterContext: AnyObject!) { 
    println("didReceiveData")
    let data = address

    var host: NSString?
    var port1: UInt16 = 0
    GCDAsyncUdpSocket.getHost(&host, port: &port1, fromAddress: address)
    println("From \(host!)")

    let gotdata = NSString(data: data, encoding: NSASCIIStringEncoding)
    //let gotdata: NSString = NSString(data: data, encoding: NSUTF8StringEncoding)
    println(gotdata)
}

This is the result:

didReceiveData
From 192.168.1.114
wþÀ¨r

As you can see, it's a bunch of strange characters.

The raw data is <100277fe c0a80172 00000000 00000000> (by writing println(data)). Here the first 4 bytes seem to be the wþÀ¨r part, and the next 4 are the IP address, which I already retrived from the getHost() function.

I can't seem to find any helper function to extract the actual data received by the UDP server. I know that the ASCII representation of the UDP reply is "hello". However, if I change this to something else, it is not reflected in the data I see in Xcode's debug part. It is always wþÀ¨r.

I have tried both with NSASCIIStringEncoding and NSUTF8StringEncoding, but the latter results in a EXC_BAD_ACCESS runtime exception.

As far as I could find, this is how people normally do it in Objective-C (inside the didReceiveData function):

NSString *msg = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

How do I find the "hello" message in the UDP reply as a string representation?

Virtuosic answered 13/9, 2014 at 15:7 Comment(0)
V
0

It is rather stupid, but removing ! from the didReceiveData data: NSData! part of the udpSocket function solved the issue.

That is, the function should be defined like this:

func udpSocket(sock: GCDAsyncUdpSocket!, didReceiveData data: NSData, fromAddress address: NSData!, withFilterContext filterContext: AnyObject!) {
    ....
}
Virtuosic answered 19/9, 2014 at 8:38 Comment(1)
The ! makes it an Optional with a implicit unwrapping. Think you might then have to downcast it to NSData. Using inline down casting "as?" and assign to local variable before use.Solvent
A
2

You assigned address to data variable in the first line, thus overwriting the value in data.

let data = address

I copied your code to try something else and noticed the error.

Alejandraalejandrina answered 8/1, 2015 at 19:27 Comment(0)
M
1

Very likely, the format of the message is simply not what you think it is, or you're sending the wrong data. Why do you believe that the packet's payload is exactly "hello" with no additional (application layer) header? Have you watched the network connection with Wireshark or tcpdump to validate?

The fact that the first byte is exactly the length of the message (16 bytes), and you indicate that bytes 3-7 are the IP address, I would strongly suspect that your message has some kind of header, and that's what you're looking at here.

Micronesian answered 14/9, 2014 at 4:42 Comment(0)
V
0

It is rather stupid, but removing ! from the didReceiveData data: NSData! part of the udpSocket function solved the issue.

That is, the function should be defined like this:

func udpSocket(sock: GCDAsyncUdpSocket!, didReceiveData data: NSData, fromAddress address: NSData!, withFilterContext filterContext: AnyObject!) {
    ....
}
Virtuosic answered 19/9, 2014 at 8:38 Comment(1)
The ! makes it an Optional with a implicit unwrapping. Think you might then have to downcast it to NSData. Using inline down casting "as?" and assign to local variable before use.Solvent

© 2022 - 2024 — McMap. All rights reserved.