iphone开发之轻松搞定原生socket 编程,阻塞与非阻塞,收发自如

简介:

iphone socket 开发

 

iphone的平台下,要进行socket开发其实有很多种的方法,开源的库Asyncsocket,官方的CFSocket,还有BSDsocket

这里要做一个简单的socket普及,这里包含在socket的设置非阻塞喝超时的控制逻辑,心跳包和线程的启动时间同步的控制。

 

这里都是标准的linux的流程

先创建一个socket

 

- (int)CSocket

{

    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)

    {

      perror("socket");

      exit(errno);    

    }

    return sockfd;

}

然后是链接

//////////////////

- (BOOL)ConnectToServer:(NSString*)addr port:(int)port

{

    their_addr.sin_family = AF_INET;

    their_addr.sin_addr.s_addr = inet_addr([addr UTF8String]);

    their_addr.sin_port = htons(port);

    bzero(&(their_addr.sin_zero), 8);

    int conn = connect(sockfd, (struct sockaddr*)&their_addr, sizeof(struct sockaddr));

    NSLog(@"Connect error no is %d:",conn);

    return misConnect;

}

 

这样子的链接是阻塞的,这样子就比较不好,可以设置成非阻塞的方式来控制超时

    /***************************************************/

    //connect之前,设成非阻塞模式

    int flags = fcntl(sockfd, F_GETFL,0);

    fcntl(sockfd,F_SETFL, flags | O_NONBLOCK);

    /***************************************************

    //这是另外一种设置成非阻塞的方式

     int flags;

     if((flags = fcntl(sockfd, F_GETFL)) < 0 )

     {

     perror("fcntl F_SETFL");

     }

     flags |= O_NONBLOCK;

     if(fcntl(sockfd, F_SETFL,flags) &lt; 0)

     {

     perror("fcntl");

     }

    ****************************************************/

设置connect后可以设置用select设置超时

/***************************************************/

    //设置超时

    fd_set          fdwrite;

    struct timeval  tvSelect;

   

    FD_ZERO(&fdwrite);

    FD_SET(sockfd, &fdwrite);

    tvSelect.tv_sec = 2;

    tvSelect.tv_usec = 0;

    int retval = select(sockfd + 1,NULL, &fdwrite, NULL, &tvSelect);

    if(retval &lt; 0)

    {

      if ( errno == EINTR )

      {

        NSLog(@"select error");

      }

      else

      {

        NSLog(@"error");

        close(sockfd);

      }

    }

    else if(retval == 0)

    {

      NSLog(@"select timeout........");

    }

    else if(retval > 0)

    {

      misConnect = YES;

    }

 

 

 

    /***************************************************/

    //connect成功之后,设成阻塞模式

    flags = fcntl(sockfd, F_GETFL,0);

    flags &= ~ O_NONBLOCK;

    fcntl(sockfd,F_SETFL, flags);

 

    /***************************************************/

    //设置不被SIGPIPE信号中断,物理链路损坏时才不会导致程序直接被Terminate

    //在网络异常的时候如果程序收到SIGPIRE是会直接被退出的。

    struct sigaction sa;

    sa.sa_handler = SIG_IGN;

    sigaction( SIGPIPE, &sa, 0 );

    /***************************************************/

 

 

然后就可以收发数据了

sendwrite两种方法都可以,你需要自己维护一个队列,控制时间等等

    NSString *str = [SendCmdArray objectAtIndex:0];

    NSData *data = [str dataUsingEncoding:NSISOLatin1StringEncoding];

//  ssize_t datalen = send(sockfd,[data bytes],[data length],0);

    ssize_t datalen = write(sockfd, [data bytes], [data length]);

    if(datalen == [data length])

    {

      NSLog(@"Send str:%@",str);

    }

 

 

如何接收数据,readrecv都可以,这是方法,你需要自己维护一个队列,控制时间等等。

    char readBuffer[512] = {0};

    NSString* readString = nil;

    int br = 0; 

    while (br = read(sockfd, readBuffer, sizeof(readBuffer)) < sizeof(readBuffer))

//  while((br = recv(sockfd, readBuffer, sizeof(readBuffer), 0)) &lt; sizeof(readBuffer))

    {

      NSLog(@"Received CMD:%s",readBuffer);

      readString = [NSString stringWithUTF8String:readBuffer];

      memset(readBuffer,0,sizeof(readBuffer));

    }

    NSLog(@"br is %d,receive exit.",br);

 

 

获取时间后就可以进行时间同步了,具体的时间同步协议要根据自己平台来设计

      time_t timep;

      struct tm *p;

      time(&timep);

      p = localtime(&timep);

      int wday = -1;//return num is (0,6),the weekday range is (1,7)

      if(p->tm_wday == 0)

        wday = 7;

      else

        wday = p-&gt;tm_wday;

      char data[256] = {0};

      sprintf(data,"0E4007%02x%02x%02x%02x%02x%02x%02x",(1900+p-&gt;tm_year)%100,(1+p-&gt;tm_mon),p-&gt;tm_mday,p-&gt;tm_hour,p-&gt;tm_min,p-&gt;tm_sec,wday);

      NSString *msgtime = [NSString stringWithUTF8String:data];

 

可以开一个线程来进行收发,处理相关的操作,想要多线程控制需要注意这个socket必须是全局可用的,因为新线程已经不在主循环了

还有如果有界面更新也需要在主线程更新

 

[NSThread detachNewThreadSelector:@selector(OnNewThread) toTarget:self withObject:nil];

 

可以用timer做一个心跳包维持通讯

 

timer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(OnHeartBeatTimer:) userInfo:nil repeats:YES];

 

结束的时候记得关掉定时器和socket

[timer invalidate];

close(sockfd);










本文转自 arthurchen 51CTO博客,原文链接:http://blog.51cto.com/arthurchen/577911,如需转载请自行联系原作者
目录
相关文章
|
4月前
|
编解码 测试技术 iOS开发
iPhone 屏幕尺寸和开发适配
【10月更文挑战第23天】iPhone 的屏幕尺寸变化给开发者带来了一定的挑战,但也为创新提供了机遇。通过深入了解不同屏幕尺寸的特点,遵循适配原则和策略,运用合适的技巧和方法,我们能够为用户提供在不同 iPhone 机型上都具有良好体验的应用。在未来,随着技术的不断进步,我们还需要持续学习和适应,以满足用户对优质应用体验的不断追求。
|
4月前
|
编解码 iOS开发 UED
响应式设计在 iPhone 开发适配中的具体应用
【10月更文挑战第23天】响应式设计在 iPhone 开发适配中扮演着至关重要的角色,它能够帮助我们打造出适应不同屏幕尺寸和用户需求的高质量应用。通过合理运用响应式设计的原则和方法,我们可以在提供良好用户体验的同时,提高开发效率和应用的可维护性。
|
5月前
|
网络协议 测试技术 网络安全
Python编程-Socket网络编程
Python编程-Socket网络编程
52 0
|
8月前
|
网络协议 开发者 Python
深度探索Python Socket编程:从理论到实践,进阶篇带你领略网络编程的魅力!
【7月更文挑战第25天】在网络编程中, Python Socket编程因灵活性强而广受青睐。本文采用问答形式深入探讨其进阶技巧。**问题一**: Socket编程基于TCP/IP,通过创建Socket对象实现通信,支持客户端和服务器间的数据交换。**问题二**: 提升并发处理能力的方法包括多线程(适用于I/O密集型任务)、多进程(绕过GIL限制)和异步IO(asyncio)。**问题三**: 提供了一个使用asyncio库实现的异步Socket服务器示例,展示如何接收及响应客户端消息。通过这些内容,希望能激发读者对网络编程的兴趣并引导进一步探索。
96 4
|
7月前
|
数据采集 iOS开发 Python
Chatgpt教你开发iPhone风格计算器,Python代码实现
Chatgpt教你开发iPhone风格计算器,Python代码实现
73 0
|
8月前
|
开发者 Python
Python Socket编程:不只是基础,更有进阶秘籍,让你的网络应用飞起来!
【7月更文挑战第25天】在网络应用蓬勃发展的数字时代,Python凭借其简洁的语法和强大的库支持成为开发高效应用的首选。本文通过实时聊天室案例,介绍了Python Socket编程的基础与进阶技巧,包括服务器与客户端的建立、数据交换等基础篇内容,以及使用多线程和异步IO提升性能的进阶篇。基础示例展示了服务器端监听连接请求、接收转发消息,客户端连接服务器并收发消息的过程。进阶部分讨论了如何利用Python的`threading`模块和`asyncio`库来处理多客户端连接,提高应用的并发处理能力和响应速度。掌握这些技能,能使开发者在网络编程领域更加游刃有余,构建出高性能的应用程序。
49 3
|
8月前
|
网络协议 Python
网络世界的建筑师:Python Socket编程基础与进阶,构建你的网络帝国!
【7月更文挑战第26天】在网络的数字宇宙中,Python Socket编程是开启网络世界大门的钥匙。本指南将引领你从基础到实战,成为网络世界的建筑师。
88 2
|
8月前
|
网络协议 程序员 视频直播
|
8月前
|
消息中间件 网络协议 网络安全
Python Socket编程:打造你的专属网络通道,基础篇与进阶篇一网打尽!
【7月更文挑战第26天】在网络编程领域,Python以简洁语法和强大库支持成为构建应用的首选。Socket编程为核心,实现计算机间的数据交换。
97 1
|
8月前
|
网络协议 安全 Java
Java中的网络编程:Socket编程详解
Java中的网络编程:Socket编程详解