xcode 在 iOS 6 中发送 udp 数据包
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13047661/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Sending udp packets in iOS 6
提问by Andrew
I am struggling to get anything to send from the iphone, I followed This GuideAt first I started off with cfSocketRef as I thought you used them for UDP and and TCP by changing protocol but I had no luck.
我正在努力从 iphone 发送任何内容,我遵循了本指南起初我从 cfSocketRef 开始,因为我认为您通过更改协议将它们用于 UDP 和 TCP,但我没有运气。
So here is the code for the BSD sockets. Nothing seems to be sending. I have a java socket server waiting on localhost:port.
所以这里是 BSD 套接字的代码。似乎什么都没有发送。我有一个 java 套接字服务器在 localhost:port 上等待。
Any ideas? or maybe a guide/sample xcode project that works.
有任何想法吗?或者可能是一个有效的指南/示例 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
回答by Martin R
First problem: You forgot to create the socket:
第一个问题:您忘记创建套接字:
if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
NSLog(@"Failed to create socket, error=%s", strerror(errno));
}
This part does not work:
这部分不起作用:
NSString *ip = @"localhost";
destination.sin_addr.s_addr = inet_addr([ip UTF8String]);
inet_addr
converts strings representing IPv4 addresses in the dot notation, such as "127.0.0.1".
inet_addr
转换以点表示法表示 IPv4 地址的字符串,例如“127.0.0.1”。
To convert a host name such as "localhost" to an IP address, you have to use gethostbyname
, or getaddrinfo
(the latter works with IPv4 and IPv6).
要将主机名(例如“localhost”)转换为 IP 地址,您必须使用gethostbyname
, or getaddrinfo
(后者适用于 IPv4 和 IPv6)。
There is another error when you check the return value of sendto
: sendto
returns the number of bytes sent in the success case, and (-1) in error case. So it should look like:
检查 的返回值时还有另一个错误sendto
:sendto
返回成功情况下发送的字节数,错误情况下返回 (-1)。所以它应该看起来像:
if (sendto(sock, ...) == -1) {
NSLog(@"did not send, error=%s",strerror(errno));
} else {
NSLog(@"did send");
}
Checking the value of errno
would have revealed your problem quickly. If you forget to create the socket, the error message is
检查 的值errno
会很快发现您的问题。如果忘记创建套接字,则错误消息为
did not send, error=Socket operation on non-socket
没有发送,错误=非套接字上的套接字操作
Remarks:
评论:
cfSocketRef
is completely unused in your function.- Why do you set the
IP_MULTICAST_IF
socket option? As far as I know, that is not needed for unicast messages, only for multicast messages.
cfSocketRef
在您的函数中完全未使用。- 为什么要设置
IP_MULTICAST_IF
socket选项?据我所知,单播消息不需要,只需要多播消息。