2

我正在努力从 iphone 发送任何东西,我遵循了本指南起初我从 cfSocketRef 开始,因为我认为您通过更改协议将它们用于 UDP 和 TCP,但我没有运气。

所以这里是 BSD 套接字的代码。似乎什么都没有发送。我有一个在 localhost:port 上等待的 java 套接字服务器。

有任何想法吗?或者可能是一个有效的指南/示例 xcode 项目。

    #import "ViewController.h"
    #include <CFNetwork/CFNetwork.h> //temp //dont leave here put it in a header
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>

    @interface ViewController ()

    @end

    @implementation ViewController


    static void socketCallback(CFSocketRef cfSocket, CFSocketCallBackType
                               type, CFDataRef address, const void *data, void *userInfo)
    {
        NSLog(@"socketCallback called");
    }
    //

    - (void)viewDidLoad
    {
        [super viewDidLoad];

        int sock = 0; /// ?
        unsigned int echolen;

        NSLog(@"starting udp testing");
        cfSocketRef = CFSocketCreate(/*CFAllocatorRef allocator*/       NULL,
                                     /*SInt32 protocolFamily*/          PF_INET,
                                     /*SInt32 socketType*/              SOCK_DGRAM,
                                     /*SInt32 protocol*/                IPPROTO_UDP,
                                     /*CFOptionFlags callBackTypes*/    kCFSocketAcceptCallBack | kCFSocketDataCallBack,
                                     /*CFSocketCallBack callout*/       (CFSocketCallBack)socketCallback,
                                     /*const CFSocketContext *context*/ NULL);



        struct sockaddr_in destination;
        memset(&destination, 0, sizeof(struct sockaddr_in));
        destination.sin_len = sizeof(struct sockaddr_in);
        destination.sin_family = AF_INET;

        NSString *ip = @"localhost";
        destination.sin_addr.s_addr = inet_addr([ip UTF8String]);
        destination.sin_port = htons(33033); //port


        NSString *msg = @"message sent from iPhone";
        /* server port */
        setsockopt(sock,
                       IPPROTO_IP,
                       IP_MULTICAST_IF,
                       &destination,
                       sizeof(destination));

        const char *cmsg = [msg UTF8String];

        echolen = strlen(cmsg);


        if (sendto(sock,
                   cmsg,
                    echolen,
                    0,
                    (struct sockaddr *) &destination,
                    sizeof(destination)) != echolen)
        {
            NSLog(@"did send");
        }
        else
        {
            NSLog(@"did not send");
        }


    }





    - (void)didReceiveMemoryWarning
    {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }

    @end
4

1 回答 1

3

第一个问题:您忘记创建套接字:

if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
    NSLog(@"Failed to create socket, error=%s", strerror(errno));
}

这部分不起作用:

NSString *ip = @"localhost";
destination.sin_addr.s_addr = inet_addr([ip UTF8String]);

inet_addr转换以点表示法表示 IPv4 地址的字符串,例如“127.0.0.1”。

要将诸如“localhost”之类的主机名转换为 IP 地址,您必须使用gethostbyname, 或getaddrinfo(后者适用于 IPv4 和 IPv6)。

检查返回值时还有另一个错误sendtosendto在成功情况下返回发送的字节数,在错误情况下返回(-1)。所以它应该看起来像:

if (sendto(sock, ...) == -1) {
    NSLog(@"did not send, error=%s",strerror(errno));
} else {
    NSLog(@"did send");
}

检查 的值errno会很快发现您的问题。如果您忘记创建套接字,则错误消息是

未发送,错误=非套接字上的套接字操作

评论:

  • cfSocketRef在您的功能中完全未使用。
  • 为什么要设置IP_MULTICAST_IF套接字选项?据我所知,单播消息不需要,只需要多播消息。
于 2012-10-24T11:20:18.960 回答