iOS从零开始学习socket编程——高并发多线程服务器

在上一篇文章《iOS从零开始学习socket编程——HTTP1.0服务器端》中我们已经简单的接触了OC搭建的HTTP服务器。

(地址http://blog.csdn.net/abc649395594/article/details/45131373

出于用户体验和鲁棒性考虑,这里把这个HTTP服务器改进成多线程的。

首先,AnsycSocket这个类是基于OC的Runloop实现的,Runloop实现了方法的异步调用但并不支持多线程。

在这里首先简单区分一下多线程和方法异步调用的区别。他们都可以避免线程的阻塞,只不过多线程是新开一个线程处理任务,处理完成之后通知主线程;而方法异步调用本质上还是在主线程里调用方法,只不过主线程并不会阻塞着等待方法的执行结果,而是继续执行原有的任务,直到方法执行完成之后才进行相应的处理。从某种意义上来说,socket编程并不总需要服务器支持多线程,因为新增一个线程本身也会增加CPU的负担,而他们的执行效果也基本类似。

然而,考虑一下这种情况,我们就应该发现多线程也有他必不可少的理由:假设用户上传一张图片并且请求对这个图片进行处理,假设图片的处理非常复杂并且涉及到大量计算,此时如果任然在主线程中执行处理图片的方法,系统的执行效率会大幅度下降,用户体验变差。如果新增一个线程,那么多核处理器的处理优势将会被充分发挥,大大提高用户体验。

因此总结起来就是:我们并不需要为每一个新的socket连接新增一个线程,确应该在处理数据的时候,充分发挥多核处理器的优势,新增线程,提高执行速度。

也正因为如此,AnsycSocket本身的回调函数是异步调用,并不支持多线程,如果在子线程中调用AnsycSocket类对象的writeData方法(向socket中写入数据)将不会起任何作用。解决方法是,将数据的处理放在新的线程,并在主线程中执行writeData方法和UI相关的改变。

重点需要修改的函数是didReadData方法:

- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
    //处理数据
}

我们只用将这个方法进行简单地修改就可以支持多线程处理数据。

- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
    __block AsyncSocket *localSocket = sock;
    __block NSData *localData = data;
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"thread = %@",[NSThread currentThread]);
        [self dealWithData:localSocket Data:localData];
    });
}

这里创建了三个block类型的对象避免在block中出现循环引用的问题。

接下来实现dealWithData方法:

- (void)dealWithData:(AsyncSocket *)sock Data:(NSData *)data{
    //这个方法和AnsycSocket的didReadData方法极为类似
    /*
        处理相关数据
    */
    dispatch_async(dispatch_get_main_queue(), ^{
        [sock writeData:data withTimeout:-1 tag:ECHO_MSG];
        [sock disconnectAfterWriting];
    });
}

可以看出,只是简单的新增了一个线程并且把原来需要在didReadData方法中实现的内容搬到了自定义的函数中。处理完成数据后,记得在主线程中写入数据即可。

PS:didReadData可能会出现无法获取数据或多次获取数据的问题。处理方法见我的另一篇博客《AsyncSocket didReadData函数详解》

地址:http://blog.csdn.net/abc649395594/article/details/45046871

最后唠叨一句:OC并不适合做服务区开发,这里写了很多只是为了加深对Socket编程本质的理解。

时间: 2024-07-31 10:10:51

iOS从零开始学习socket编程——高并发多线程服务器的相关文章

iOS从零开始学习socket编程——HTTP1.0服务器端

在前一篇文章<iOS从零开始学习socket编程--HTTP1.0客户端>中已经简单的介绍过了Socket编程和一些基本原理.并且实现了简单的iOS客户端(原文地址:http://blog.csdn.net/abc649395594/article/details/45081567) 这里再简单介绍一下如何使用OC搭建socket的服务器端.虽然这并不是一个好的解决方案,通常我们使用Java或者PHP抑或NodeJS来搭建服务器后台.但是还是有必要了解一下OC的做法,顺便加深对Socket编程

iOS从零开始学习socket编程——HTTP1.0客户端

在开始socket编程之前,首先需要明确几个概念: 1.网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket. 2.socket中文名为"套接字",是基于TCP/IP协议通信机制. 3.客户端的socket连接需要指定主机的ip地址和端口,ip地址类似于家庭地址,用于唯一确认一台主机,而端口类似于门牌号,用于唯一确认主机上的某一个程序. 我们模拟一次HTTP的请求.首先在终端中输入 telnet 202.118.1.7 80 我们会得到这样的提示 T

linux网络编程-----&gt;高并发---&gt;多线程并发服务器

做网络服务的时候并发服务端程序的编写必不可少.前端客户端应用程序是否稳定一部分取决于客户端自身,而更多的取决于服务器是否相应时间够迅速,够稳定. 常见的linux并发服务器模型: 多进程并发服务器 多线程并发服务器 select多路I/O转接服务器 poll多路I/O转接服务器 epool多路I/O转接服务器. 本次主要讨论多线程并发服务器模型: 使用多线程模型开发服务时需要考虑以下问题 1.  调整进程内最大文件描述符上限. 2.  线程如有共享数据, 考虑线程同步. 3.  服务于客户端线程

socket编程之并发回射服务器3

在socket编程之并发回射服务器一文中,服务器采用多进程的方式实现并发,本文采用多线程的方式实现并发. 多线程相关API: // Compile and link with -pthread int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); int pthread_join(pthread_t thread, void **

socket编程,简单多线程服务端测试程序

socket编程,简单多线程服务端测试程序 前些天重温了MSDN关于socket编程的WSAStartup.WSACleanup.socket.closesocket.bind.listen.accept.recv.send等函数的介绍,今天写了一个CUI界面的测试程序(依赖MFC)作为补充.程序功能简介如下: 1:一个线程做监听用. 2:监听线程收到客户端连接后,创建新线程接收客户端数据.所有对客户端线程将加入容器,以便管理. 3:服务端打印所有客户端发来的信息. 4:服务端CUI界面输入数字

[转] 3个学习Socket编程的简单例子:TCP Server/Client, Select

以前都是采用ACE的编写网络应用,最近由于工作需要,需要直接只用socket接口编写CS的代码,重新学习这方面的知识,给出自己所用到的3个简单例子,都是拷贝别人的程序.如果你能完全理解这3个例子,估计socket编程就已经基本入门了. 建议:1) 多多查查所用到的网络接口; 2) 最好有一本书,如UNIX环境高级编程,UNIX网络编程,可查询:3) 可以直接使用书上的例子更好. http://blog.csdn.net/zhenjing/article/details/4770490 TCP C

分布式=高并发=多线程

当提起这三个词的时候,是不是很多人都认为分布式=高并发=多线程? 当面试官问到高并发系统可以采用哪些手段来解决,或者被问到分布式系统如何解决一致性的问题,是不是一脸懵逼? 确实,在一开始接触的时候,不少人都会将三者混淆,误以为所谓的分布式高并发的系统就是能同时供海量用户访问,而采用多线程手段不就是可以提供系统的并发能力吗?实际上,他们三个总是相伴而生,但侧重点又有不同. 什么是分布式? 分布式更多的一个概念,是为了解决单个物理服务器容量和性能瓶颈问题而采用的优化手段.该领域需要解决的问题极多,在

Socket编程总结—Android手机服务器与多个Android手机客户端之间的通信(非阻塞)

根据前两周写的关于Socket编程的网络通信的代码,现在对有关知识和注意事项进行总结如下: 1.首先说下Android NIO中有关Socket编程的类: 1)ServerSocketChannel类:服务器套接字通道相当于传统IO下的ServerSocket,通过ServerSocketChannel的socket()可以获得传统的ServerSocket,反过来使用ServerSocket的getChannel()可以获得ServerSocketChannel对象:实例化ServerSock

基于tomcat响应处理模型实现的高并发web服务器

在上一篇博客中,一个简单的AIOweb处理例子,可以看到AIO异步处理,依赖操作系统完成IO操作的Proactor处理模型确实很强大,可以是实现高并发,高响应服务器的不错选择,但是在tomcat中的connector的处理模型还依旧是基于NIO的处理,当然,我认为这可能会在以后的版本进行改进,但另一方面,我更认为AIO的负载控制方面的处理可能是比较难的,因为AIO api并没有提供我们对分配线程组的处理,而只是提供一个线程组,交给操作系统去解决io处理上的问题,所以,这可能会给需要复杂处理的负载