UDP包通信

转自:https://developer.apple.com/library/mac/#documentation/NetworkingInternet/Conceptual/NetworkingTopics/Articles/UsingSocketsandSocketStreams.html

The recommended way to send and receive UDP packets is by combining the POSIX API and either the CFSocket or GCD APIs. To use these APIs, you must perform the following steps:

  1. Create a socket by calling socket.

  2. Bind the socket by calling bind. Provide a sockaddr struct that specifies information about the desired port and family.

  3. Connect the socket by calling connect (optional).

    Note that a connected UDP socket is not a connection in the purest sense of the word. However, it provides two advantages over an unconnected socket. First, it removes the need to specify the destination address every time you send a new message. Second, your app may receive errors when a packet cannot be delivered. This error delivery is not guaranteed with UDP, however; it is dependent on network conditions that are beyond your app’s control.

From there, you can work with the connection in three ways:

  • If you are using GCD for run loop integration (recommended), create a dispatch source by calling dispatch_source_create. Assign an event handler to the dispatch source. Optionally assign a cancellation handler. Finally, pass the dispatch source to the dispatch_resume function to begin handling events.

  • If you are using CFSocket for integration, this technique is somewhat more complicated, but makes it easier to interface your code with some Cocoa APIs. However, CFSocket objects use a single object to represent a connection (much like sockets at the POSIX layer), whereas most Cocoa APIs are designed to interface with stream-based APIs that use separate objects for sending and receiving. As a result, some Cocoa APIs that expect read or write streams may be difficult to use in conjunction with CFSocketRef objects.

    To use CFSocket:

    1. Create an object to use for managing the connection. If you are writing Objective-C code, this can be a class. If you are writing pure C code, this should be a Core Foundation object, such as a mutable dictionary.

    2. Create a context object to describe that object.

      CFSocketContext ctxt;
       
      ctxt.version = 0;
      ctxt.info = my_context_object;
      ctxt.retain = CFRetain;
      ctxt.release = CFRelease;
      ctxt.copyDescription = NULL;
    3. Create a CFSocket object (CFSocketRef) for the CFSocketNativeHandle object by calling CFSocketCreateWithNative.

      Be sure to set (at minimum) the kCFSocketDataCallBack flag in your callBackTypes parameter value. Do not set thekCFSocketAcceptCallBack flag.

      You’ll also need to provide a pointer to a CFSocketCallBack callback function as the callout parameter value.

      For example:

      CFSocketRef connection = CFSocketCreateWithNative(kCFAllocatorDefault,
          sock,
          kCFSocketDataCallBack,
          handleNetworkData,
          &ctxt);
    4. Tell Core Foundation that it is allowed to close the socket when the underlying Core Foundation object is invalidated.

      CFOptionFlags sockopt = CFSocketGetSocketFlags(connection);
       
      sockopt |= kCFSocketCloseOnInvalidate | kCFSocketAutomaticallyReenableReadCallBack;
      CFSocketSetSocketFlags(connection, sockopt);
    5. Create an event source for the socket and schedule it on your run loop.

      CFRunLoopSourceRef socketsource = CFSocketCreateRunLoopSource(
          kCFAllocatorDefault,
          connection,
          0);
       
      CFRunLoopAddSource(CFRunLoopGetCurrent(), socketsource, kCFRunLoopDefaultMode);

    Whenever new data becomes available, the data handler callback gets called. In your callback, if the value of the callbackType parameter iskCFSocketConnectCallBack, check the data parameter passed into the callback. If it is NULL, you have connected to the host. You can then send data using the CFSocketSendData function.

    When you are finished with the socket, close and invalidate it by calling the CFSocketInvalidate function.

    At any point, you can also access the underlying BSD socket by calling the CFSocketGetNative function.

    For more information, see CFSocket Reference. For sample code, see the UDPEcho sample code project.

  • If you are using pure POSIX sockets, use the select system call to wait for data, then use the read and write system calls to perform I/O. To learn more about sending and receiving UDP packets with the POSIX socket API, read the UNIX Socket FAQ at http://developerweb.net/.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值