【问题标题】:Objective-c sockets - Can't correctly receive string in udp messageObjective-c 套接字 - 无法正确接收 udp 消息中的字符串
【发布时间】:2012-12-20 12:34:08
【问题描述】:

当动态创建此字符串时(当我将其值设置为我的代码中的另一个变量时),我无法接收我通过 UDP 数据包发送的字符串。不同的是,当我在创建这个字符串时为字符串设置了一个常量值时,这个问题不会出现。 这是我用来发送字符串的方法:

- (void) sendUDPMessage {
 int sockfd;
 struct sockaddr_in server_addr;
 char myBroad[]="255.255.255.255";
 struct hostent *hptr = gethostbyname(myBroad);
 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
 bzero(&server_addr, sizeof(struct in_addr));
 server_addr.sin_family = AF_INET;
 server_addr.sin_port = htons(15000);
 server_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
 memcpy(&server_addr.sin_addr, hptr->h_addr_list[0], sizeof(struct in_addr));
 int opt = 1;
 setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(int));
 NSString *string = [NSString stringWithFormat:@"%@ %@",user.name,user.surname];
 sendto(sockfd, &string, sizeof(string), 0, (struct sockaddr*)&server_addr, sizeof server_addr);
 NSLog(@"message sent : %@",string);
}

这是接收udp数据包的方法:

- (void) server {
 int serverfd;
 struct sockaddr_in server_addr;
 struct sockaddr_in client_addr;
 serverfd = socket(AF_INET, SOCK_DGRAM, 0);
 bzero(&server_addr, sizeof(struct sockaddr_in));
 server_addr.sin_family = AF_INET;
 server_addr.sin_port = htons(15000);
 server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
 bind(serverfd, (struct sockaddr *) &server_addr, sizeof(struct sockaddr_in));
 socklen_t clisize = sizeof(struct sockaddr_in);
 bzero(&client_addr, clisize);
 while (1) {
    NSString *string=@"";
    NSLog(@"wainting for messages");
    recvfrom(serverfd, &string, 200, 0, (struct sockaddr *) &sin, &clisize);
    NSLog(@"message received : %@",string);
 }
}

如果我定义 NSString * string = @"hello!";我可以正确接收字符串的内容。当我尝试发送 NSObject 时也存在同样的问题。 我错过了什么?谢谢!

【问题讨论】:

    标签: objective-c sockets nsstring


    【解决方案1】:

    如果您的目标是将套接字用于某些实际目的,您应该尝试 GCDAsyncSocket(和相关类)。

    如果这只是为了深入了解套接字的工作原理(和/或如果您也想在 C 项目中使用它),这里是您的代码的固定版本:

    - (void) sendUDPMessage {
     int sockfd;
     struct sockaddr_in server_addr;
     char myBroad[]="255.255.255.255";
     struct hostent *hptr = gethostbyname(myBroad);
     sockfd = socket(AF_INET, SOCK_DGRAM, 0);
     bzero(&server_addr, sizeof(struct in_addr));
     server_addr.sin_family = AF_INET;
     server_addr.sin_port = htons(15000);
     server_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
     memcpy(&server_addr.sin_addr, hptr->h_addr_list[0], sizeof(struct in_addr));
     int opt = 1;
     setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(int));
     NSString *string = [NSString stringWithFormat:@"%@ %@",user.name,user.surname];
    
     // sendto(sockfd, &string, sizeof(string), 0, (struct sockaddr*)&server_addr, sizeof server_addr);
     // get a pointer to the raw string bytes in UTF-8 encoding:
     const char *bytes = string.UTF8String;
     // send the bytes, using strlen() to get the number of bytes in the UTF-8 string
     // Note! this may not be equal to string.length, which gives the number of UTF-8 chars.
     sendto(sockfd, bytes, strlen(bytes), 0, (struct sockaddr*)&server_addr, sizeof server_addr);
    
     NSLog(@"message sent : %@",string);
    }
    

    这是接收udp数据包的方法:

    - (void) server {
     int serverfd;
     struct sockaddr_in server_addr;
     struct sockaddr_in client_addr;
     serverfd = socket(AF_INET, SOCK_DGRAM, 0);
     bzero(&server_addr, sizeof(struct sockaddr_in));
     server_addr.sin_family = AF_INET;
     server_addr.sin_port = htons(15000);
     server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
     bind(serverfd, (struct sockaddr *) &server_addr, sizeof(struct sockaddr_in));
     socklen_t clisize = sizeof(struct sockaddr_in);
     bzero(&client_addr, clisize);
    
    while (1) {
        NSLog(@"waiting for messages");
        char buf[1024]; // this is a static buffer to receive raw bytes
        int bytesread = recvfrom(serverfd, buf, 1024, 0, (struct sockaddr *) &sin, &clisize);
        if ( bytesread > 0 )
        {
            NSString *string = [[NSString alloc] initWithBytes:buf length:bytesread encoding:NSUTF8StringEncoding];
            NSLog(@"message received : %@",string);
            // for non-arc projects don't forget to release string
        }
    }
    }
    

    (未经测试)

    此代码中还存在各种问题,仅供快速演示使用。例如。应该检查所有返回值,应该处理所有错误,您应该知道调用可能会阻塞(除非您特别阻止这种情况),您应该在创建 NSString 之前收到整个消息(例如,如果收到的数据包是大于缓冲区;您不能天真地部分地执行此操作,因为 UTF-8 具有多字节字符)

    您已被警告!

    【讨论】:

    • 这肯定是一个初步的开始,当基本操作正常工作时,所有需要的检查都将被执行!感谢您的帮助!
    【解决方案2】:

    您的代码正在尝试发送和接收 NSString 对象。 NSString 不是字符序列。它是一个对象。对象的内容对接收者没有意义。您需要发送字符串中包含的字符。

    在发送端,您需要发送 NSString 中包含的字符(通过UTF8String:cStringUsingEncoding: 获得)。在接收端,您需要接收文本,然后使用+stringWithUTF8String:+stringWithCString:encoding: 创建一个NSString

    【讨论】:

    • 这个可能性我已经考虑过了。事实上,我试图将我的 NSString 转换为 const char,但我不断收到诸如 ‡Ï/ 之类的东西。我认为调试器崩溃的那一刻是我尝试通过应用 stringWithUTF8String 从接收到的字符中获取 NSString 的那一刻。
    猜你喜欢
    • 2017-09-04
    • 2021-06-13
    • 1970-01-01
    • 2016-02-28
    • 2011-08-11
    • 2015-11-26
    • 2015-01-02
    • 2013-04-28
    • 2013-02-08
    相关资源
    最近更新 更多