2012-12-20 52 views
1

我遇到了麻煩,它接收到我用UDP數據包發送的字符串,當這個字符串是動態創建的(當我設置其值等於另一個變量在我的代碼中)。這個問題並沒有出現,當我創建一個不同的字符串時,我給它設置了一個常量值。 這裏是我用來發送字符串的方法:Objective-c插座 - 無法正確接收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 *[email protected]""; 
    NSLog(@"wainting for messages"); 
    recvfrom(serverfd, &string, 200, 0, (struct sockaddr *) &sin, &clisize); 
    NSLog(@"message received : %@",string); 
} 
} 

如果我定義的NSString *字符串= @「你好!」;我可以正確接收字符串的內容。當我嘗試發送一個NSObject時也存在同樣的問題。 我錯過了什麼?謝謝!

回答

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具有多字節字符,你不能在零件上做到這一點)

你已被警告!

+0

這確實是一個初始的劃痕,所有需要的檢查都將在基本操作正常工作時執行!謝謝您的幫助! – whiplash

-1

關閉我的頭頂嘗試改變 NSString * string = @「」; 至 NSStirng * string = nil;

+0

感謝您的提示,但沒有任何改變!我應該補充說,一旦收到消息,調試器有時會崩潰。如果我將NSString轉換爲一個常量字符,我稍後發送,至少崩潰問題已解決,但接收的字符包含隨機字符。 – whiplash

+0

-1對不起,但這個答案沒有意義 – mvds

0

您的代碼正試圖發送和接收NSString對象。 NSString不是一個字符序列。這是一個對象。對象的內容對接收者沒有任何意義。您需要發送字符串中包含的字符。

在發送端,您需要發送NSString中包含的字符(通過UTF8String:cStringUsingEncoding:獲取)。在接收端,你需要接受的文本,然後創建一個NSString與+stringWithUTF8String:+stringWithCString:encoding:

+0

這是我已經考慮到的可能性。事實上,我試圖將我的NSString轉換爲一個const char,但我一直在接收像‡Ï/這樣的東西。我認爲調試器崩潰的時刻是我嘗試通過應用stringWithUTF8String從接收到的字符中獲取NSString的那一刻。 – whiplash