Ios CFSocket数据回调
在iPhone应用程序中,我从现有的本机UDP套接字创建了一个CFSocket对象,并在套接字接收到一些数据时设置一个数据回调。然后我将其添加到我的主程序循环中:Ios CFSocket数据回调,ios,iphone,sockets,cfsocket,Ios,Iphone,Sockets,Cfsocket,在iPhone应用程序中,我从现有的本机UDP套接字创建了一个CFSocket对象,并在套接字接收到一些数据时设置一个数据回调。然后我将其添加到我的主程序循环中: //Set socket descriptor field cbData.s = udpSocket.getSocketDescriptor(); CFSocketContext udpSocketContext; memset(&udpSocketContext, 0, sizeof(udp
//Set socket descriptor field
cbData.s = udpSocket.getSocketDescriptor();
CFSocketContext udpSocketContext;
memset(&udpSocketContext, 0, sizeof(udpSocketContext));
udpSocketContext.info = &cbData;
cbData.socketRef = CFSocketCreateWithNative(NULL, cbData.s, kCFSocketDataCallBack, &getSocketDataCallBack, &udpSocketContext);
cbData.runLoopSourceRef = CFSocketCreateRunLoopSource( NULL, cbData.socketRef, 0);
CFRunLoopAddSource(CFRunLoopGetMain(), cbData.runLoopSourceRef, kCFRunLoopCommonModes);
我每5毫秒从一个单独的Mac服务器应用程序通过WiFi发送1024字节的数据报,并在iPhone上的getSocketDataCallBack例程中接收它们
我希望getSocketDataCallBack每5毫秒调用一次(以匹配从Mac发送的数据报的周期),这在大多数情况下都会发生。但是,这些调用通常会延迟10秒或100毫秒。此后,我会得到一个快速的回调序列(毫秒的分数),以检索在延迟期间堆积的多个数据报
由于iOS显然保留了延迟的数据报
- 有没有办法从系统中获取所有延迟的数据报
一次而不是一次又一次地调用getSocketDataCallBack
接二连三地
[我确实查询回调ala中有多少字节可用:
但“numBytesReceived”始终报告为1024。]CFDataRef dataRef = (CFDataRef)data; numBytesReceived = CFDataGetLength(dataRef);
- 或者,有没有办法改进/减少套接字回调 通过其他方式的时间可变性
#import <stdio.h>
#import <string.h>
#import <stdlib.h>
#import <unistd.h>
#import <pthread.h>
#import <sys/socket.h>
#import <sys/un.h>
#import <sys/stat.h>
#import <sys/types.h>
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
int setup(const char *ipcNode) {
int sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sockfd == -1) {
return -1;
}
struct sockaddr_un sa = {0};
sa.sun_len = sizeof(sa);
sa.sun_family = AF_UNIX;
strcpy(sa.sun_path, ipcNode);
remove(sa.sun_path);
if (bind(sockfd, (struct sockaddr*)&sa, sizeof(struct sockaddr_un)) == -1) {
close(sockfd);
return -1;
}
// start up worker thread
pthread_attr_t at;
pthread_attr_init(&at);
pthread_attr_setdetachstate(&at, PTHREAD_CREATE_DETACHED);
pthread_t th;
pthread_create(&th, &at, workerThread, (void *)(long)(sockfd));
return 1;
}
如果您在客户端工作,事情会变得容易一些。您将通过connect()调用获得一个读/写fd。然后使用fd创建CFSockeRef并添加到run循环
希望这有帮助
编辑:如何使用POSIX select()等待。在工作线程上使用POSIX select()等待比套接字回调更简单。如果您在客户端,则:
int sockfd = socket(...);
bind(sockfd, ...)
connect(sockfd, ...);
while (1) {
int nfds = sockfd+1;
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(sockfd, &rfds);
int retval = select(nfds, &rfds, NULL, NULL, NULL);
if (retval == -1) break;
if (retval > 0) {
uint8_t rxdata[1024];
size_t nr = read(sockfd, rxdata, 1024);
if (!nr) {
// socket closed.
break;
}
// do your rx process here
}
}
在工作线程上运行上述代码。这可能不是真的,但如果要添加到主线程的运行循环,请尝试创建另一个线程,然后在该线程中运行运行循环,看看是否仍有偶尔的延迟。请多加一条注释。可能开销最小的“回调”方案应该是等待w/posix select()。如果上面的方法不起作用,我会在另一个线程中尝试select()。谢谢,贝西奥。我正在考虑创建另一个线程。我的回调函数如下:
void getSocketDataCallBack(CFSocketRef CFSocketRef,CFSocketCallBackType cbType,CFDataRef address,const void*data,void*info)
。如何使用NSThread实现这一点?在上面的相关问题中,对CFRunLoopGetCurrent()的调用是否会返回与CFRunLoopAddSource()调用中的CFRunLoopGetMain()相同的结果?我在想,在这种情况下,他们会返回相同的东西,但我想了解它多一点。谢谢由于评论时间太长,我在下面的回答中写道。非常感谢,贝希奥!当我在客户端对整个设置进行编程时,我能够删除中间步骤(您的socketDataCallback
),并从workerThread
设置我的客户端回调版本,我有更多的测试要做,但回调时间的可变性似乎更小。有时,系统仍然会延迟套接字读取回调,但我可能无法完全缓解这个问题,因为我正在尝试在非实时IOSO中进行实时音频播放。因此,在测试之后,回调的时间变化仍然比我希望的要大。我尝试按如下方式设置新线程的策略和优先级,但没有效果:pthread\u attr\u setinheritsched(&at,pthread\u EXPLICIT\u SCHED);pthread_attr_setschedpolicy(&at,SCHED_FIFO)代码>然后:int策略;结构sched_param param;pthread_getschedparam(th、策略和参数);param.sched_优先级=32//默认值=31 pthread_setschedparam(th、policy和param)代码>还有其他想法吗?用POSIX select()调用代替工作线程中的套接字回调来等待怎么样?如果增加工作线程的调度优先级并使用select()调用等待,我认为这是我们能做的最好的事情。我相信使用select()等待比套接字回调开销小。
#import <stdio.h>
#import <string.h>
#import <stdlib.h>
#import <unistd.h>
#import <pthread.h>
#import <sys/socket.h>
#import <sys/un.h>
#import <sys/stat.h>
#import <sys/types.h>
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
int setup(const char *ipcNode) {
int sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sockfd == -1) {
return -1;
}
struct sockaddr_un sa = {0};
sa.sun_len = sizeof(sa);
sa.sun_family = AF_UNIX;
strcpy(sa.sun_path, ipcNode);
remove(sa.sun_path);
if (bind(sockfd, (struct sockaddr*)&sa, sizeof(struct sockaddr_un)) == -1) {
close(sockfd);
return -1;
}
// start up worker thread
pthread_attr_t at;
pthread_attr_init(&at);
pthread_attr_setdetachstate(&at, PTHREAD_CREATE_DETACHED);
pthread_t th;
pthread_create(&th, &at, workerThread, (void *)(long)(sockfd));
return 1;
}