1

当动态创建此字符串时(当我将其值设置为等于我的代码中的另一个变量之一时),我无法接收使用 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 时也存在同样的问题。我错过了什么?谢谢!

4

2 回答 2

0

如果您的目标是将套接字用于某些实际目的,您应该尝试 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 有多字节字符)

你被警告了!

于 2012-12-20T13:38:19.747 回答
0

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

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

于 2012-12-20T13:15:48.863 回答