IOS GCDasyncsocket 简书发送数据消息头和消息体要分两次写入吗

GCDAsyncSocket使用(ipv6适配) - 简书
<div class="fixed-btn note-fixed-download" data-toggle="popover" data-placement="left" data-html="true" data-trigger="hover" data-content=''>
写了2584字,被75人关注,获得了72个喜欢
GCDAsyncSocket使用(ipv6适配)
在此之前发给链接关于socket ipv6的适配问题 之前写的socket不怎么清晰,所以很多人过来咨询,打算重新再整理下。顺便把大家的问题总结下首先得大概了解TCP原理和UDP的一点区别!当然了我自己也是似懂非懂的状态,这些还是要靠自己慢慢摸索,多看看别人的blog见解,网上一搜一大把。GCDAsyncSocket是IOS中TCP通讯使用的一个第三方库。至于的它的什么三次握手啊这些网上多的很,我也不做过多的重复。下面就从demo开始吧!开始之前应该都能想到socket是贯穿整个项目使用,所以尽量提取出来,写成单例
至于为何把connet方法提出来,主要是为了断开重连方便链接是否成功和命令是否发送成功的回调 delegate已经提供 我们只要调用方法就可以
有心的童靴可以看到我在链接是否成功里面的 写了readDataWithTimeout的方法 其实是告诉socket你的超时时间 链接成功后肯定要进行数据传输 这部分的各个项目的情况不一样 ,一般都不是单一的命令 所以我建议把具体的命令函数单独写成类
我这里是提出命令数据单独进行处理,可以给大家看看 当然每个公司的协议不同仅作参考
最后就是接受数据的回调,
在这里跟各位童靴说下 ,很多碰到这种问题 ,开始的时候能够接收到返回的数据 过来一会就不能,经常这种情况,我看了下 大家都是把timeout写成 10啊 30啊固定的时间,这里我和大家解释下,这个函数的意义,readDataWithTimeout
它底层相当于开了线程等待接收数据 过了这个时间 就自动停止,-1表示一直接收
。最后就是socket关闭的方法 DidClose DidDisconnect.这次更新就到这吧!谢谢!
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
被以下专题收入,发现更多相似内容:
记录一些开发过程中学习的知识或者遇到的问题,欢迎大家投稿。一起分享,一起进步
· 7437人关注
· 2093人关注
收录iOS相关优质文章
· 1482人关注
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
选择支付方式:下次自动登录
现在的位置:
& 综合 & 正文
GCDAsyncSocket
Asynchronous socket networking library for Mac and iOS
对于Mac和IOS的异步Socket
CocoaAsyncSocket provides easy-to-use and powerful asynchronous socket libraries for Mac and iOS. The classes are described below.
CocoaAsyncSocket为Mac和IOS提供了简单易用和功能强大的异步Socket库。这些类和描述如下所示。
GCDAsyncSocket and AsyncSocket are TCP/IP socket networking libraries. Here are the key features available in both:
GCDAAsyncSocket和AsyncSocket都是TCP/IP套接字网络库。这里是关键的特性可用于以下情况
Native objective-c, fully self-contained in one class.
Native objective-c,完全包含一个类里
  No need to muck around with sockets or streams. This class handles everything for you.
  不需要混淆Socket套接字和流。这个类为你提供了一切。
Full delegate support
全delegate支持
  Errors, connections, read completions, write completions, progress, and disconnections all result in a call to your delegate method.
  错误,连接,读完成,写完成,处理和断开连接的所有结果都在你调用的delegate委托的方法中。
Queued non-blocking reads and writes, with optional timeouts.
读写无堵塞排队,可选超时
  You tell it what to read or write, and it handles everything for you. Queueing, buffering, and searching for termination sequences within the stream - all handled for you automatically.
  你告诉它去读写什么,它将为你处理一切。排列、缓存和在流内寻找终止序列--所有的一切都将为你自动完成
Automatic socket acceptance.
Socket自动接收验证
  Spin up a server socket, tell it to accept connections, and it will call you with new instances of itself for each connection.
  启动一个Socket服务器,告诉它一个接收连接,它将自己为每一个连接创建一个新的连接实例。
Support for TCP streams over IPv4 and IPv6.
支持IPV4和IPV6上得TCP流
  Automatically connect to IPv4 or IPv6 hosts. Automatically accept incoming connections over both IPv4 and IPv6 with a single instance of this class. No more worrying about multiple sockets
  自动连接到IPV4或IPV4的主机上。用一个类的单一实例自动接收一个传入的连接在IPV4和IPV6上,不用担心多个Socket。
Support for TLS / SSL
支持TLS/SSL
  Secure your socket with ease using just a single method call. Available for both client and server sockets.
  它将确保你的Socket轻松,使用单一的一个方法调用。对于Socket客户端和服务器都适用
GCDAsyncSocket is built atop Grand Central Dispatch:
GCDAsyncSocket是建立在
Fully GCD based and Thread-Safe
完全基于GCD和线程安全
  It runs entirely within its own GCD dispatch_queue, and is completely thread-safe. Further, the delegate methods are all invoked asynchronously onto a dispatch_queue of your choosing. This means parallel operation of your socket code, and your delegate/processing
  它完全运行在自己的GCD的调度队列上,并且它是完全线程安全的。进一步的说,委托方法在你选择的调度队列上都是异步调用的。这意味着你将平行的操作你的socket和委托代码。
The Latest Technology & Performance Optimizations
最新的技术和性能优化
  Internally the library takes advantage of technologies such as
optimize buffer allocations. In other words, peak performance.
  在内部,库利用诸如限制系统调用和优化缓存区分配。总之,这是巅峰之作。
AsyncSocket wraps CFSocket and CFStream:
AsyncSocket包含CFSocket和CFStream:
Fully Run-loop based
  Use it on the main thread or a worker thread. It plugs into the NSRunLoop with configurable modes.
  在主线程或工作线程上运用它。它使用配置模型插入到NSRunLoop中
GCDAsyncUdpSocket and AsyncUdpSocket are UDP/IP socket networking libraries. Here are the key features available in both:
GCDAsyncSocket和AsyncSocket都是UDP/IP套接字网络库。这里是关键的特性可用于以下情况:
Native objective-c, fully self-contained in one class.
Native objective-c,完全包含一个类里
  No need to muck around with low-level sockets. This class handles everything for you.
  不需要和底层套接字混淆。这些类为你提供了所有的东西
Full delegate support.
  Errors, send completions, receive completions, and disconnections all result in a call to your delegate method.
  错误,发送完成,接收完成和断开连接的结果都在你调用的委托方法中
Queued non-blocking send and receive operations, with optional timeouts.
读写无堵塞排队,可选超时
  You tell it what to send or receive, and it handles everything for you. Queueing, buffering, waiting and checking errno - all handled for you automatically.
  你告诉它发送或接收什么,它为你提供所有的东西。队列,缓存,等待和检查错误--都是为你自动提供
Support for IPv4 and IPv6.
支持IPV4和IPV6
  Automatically send/recv using IPv4 and/or IPv6. No more worrying about multiple sockets.
  自动使用IPV4和或IPV6发送和接收。不用担心多个Socket
GCDAsyncUdpSocket is built atop Grand Central Dispatch:
GCDAsyncUdpSocket是建立在
Fully GCD based and Thread-Safe
完全基于GCD和线程安全It runs entirely within its own GCD dispatch_queue, and is completely thread-safe. Further, the delegate methods are all invoked asynchronously onto a dispatch_queue of your choosing. This means parallel operation of your socket code, and your delegate/processing
  它完全运行在自己的GCD的调度队列上,并且它是完全线程安全的。进一步的说,委托方法在你选择的调度队列上都是异步调用的。这意味着你将平行的操作你的socket代码和委托代码。
AsyncUdpSocket wraps CFSocket:
AsyncUdpSocket包含CFSocket:
Fully Run-loop based
  Use it on the main thread or a worker thread. It plugs into the NSRunLoop with configurable modes.
  在主线程或工作线程上运用它。它使用配置模型插入到NSRunLoop中
&&&&推荐文章:
【上篇】【下篇】iOS-----简易地CocoaAsyncSocket使用_iOS开发_
iOS-----简易地CocoaAsyncSocket使用
来源:人气:507
CocoaAsyncSocket使用
代理的.h文件
//GCDAsyncSocketDelegate执行代理对象
#import &Foundation/Foundation.h&
#import "CocoaAsyncSocket.h"
typedef void(^DidReadData)(NSDictionary* didReadData);
GCDAsyncSocketDelegate执行代理对象
@interface NSObjectGCDAsyncSocket : NSObject&GCDAsyncSocketDelegate&
接收到数据的处理
@operty(nonatomic,copy)DidReadData didReadD
发送的数据
如果添加新键值则需要先开辟内存
@property(nonatomic,retain)NSMutableDictionary* writeD
发送链接请求
-(BOOL)startC
+(NSObjectGCDAsyncSocket*)defaultS
NSObjectGCDAsyncSocket.m
attendance
#import "NSObjectGCDAsyncSocket.h"
@implementation NSObjectGCDAsyncSocket
GCDAsyncSocket*
+(NSObjectGCDAsyncSocket *)defaultSocket
// socket只会实例化一次
static NSObjectGCDAsyncSocket* socket=
// 保证线程安全,defaultSocket只执行一次
static dispatch_once_
dispatch_once(&once, ^
socket=[[NSObjectGCDAsyncSocket alloc] init];
@return self
-(instancetype)init
self=[super init];
socket=[[GCDAsyncSocket alloc] initWithDelegate:self
delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
发送链接请求
-(BOOL)startConnect
// 先确定断开连接再开始链接
if (socket.isConnected)
NSLog(@"主动断开");
[socket disconnect];
isSuccess= [socket connectToHost:SocketHost
onPort:SocketPort
error:&error];
if (error)
NSLog(@"error.localizedDescrtion:%@",error.localizedDescription);
return isS
#pragma mark - GCDAsyncSocketDelegate
@param sock sock实例
@param host IP
@param port 端口
-(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host
port:(uint16_t)port
NSLog(@"%s",__FUNCTION__);
NSLog(sock.isConnected?@"YES":@"NO");
if (sock.isConnected)
// NSString上传需要加"\n"分隔符方可上传成功
[sock writeData:[@"ABCABCABCABCABCABC\n" dataUsingEncoding:NSUTF8StringEncoding]
withTimeout:-1
NSDictionary* nsDictionaryUser=@{@"gpsinfo":@"Gpsinfo",
@"pswd":self.pass,
@"gpstype":@(2015),
@"name":self.name,
NSDictionary* agrement=@{@"vertion":@(1),
@"type1":@(2),
@"type2":@(0),
@"type3":@(0)};
if ([NSJSONSerialization isValidJSONObject:self.writeData])
NSLog(@"isValidJSONObject");
// 先转NSData再转NSString是为了保证NSDictionary格式不变
NSData *nsDataUser= [NSJSONSerialization dataWithJSONObject:self.writeData
options:NSJSONWritingPrettyPrinted
error:&error];
NSString* json=[[NSString alloc] initWithData:nsDataUser
encoding:NSUTF8StringEncoding];
NSLog(@"nsDictionaryUser:%@",json);
json=[json stringByReplacingOccurrencesOfString:@"\n"
withString:@""];
json=[json stringByReplacingOccurrencesOfString:@" "
withString:@""];
json=[json stringByAppendingString:@"\n"];
NSLog(@"json:%@",json);
[sock writeData:[json dataUsingEncoding:NSUTF8StringEncoding]
withTimeout:-1
// 保持读取的长连接
[sock readDataWithTimeout:-1
if (error)
NSLog(@"localizedDescription:%@",[error localizedDescription]);
NSLog(@"localizedFailureReason:%@",[error localizedFailureReason]);
发送数据成功
@param sock
@param tag
-(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag
NSLog(@"didWriteDataWithTag");
已经获取到数据
@param sock sock实例
@param data 获取到的数据
@param tag
-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data
withTag:(long)tag
NSLog(@"%s",__FUNCTION__);
NSError* error=
NSDictionary* json=(NSDictionary*)[NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingAllowFragments
error:&error];
NSLog([NSJSONSerialization isValidJSONObject:json]?@"is ValidJSONObject":@"is't ValidJSONObject");
if (error)
NSLog(@"socketError1:%@",[error localizedDescription]);
NSLog(@"socketError2:%@",[error localizedFailureReason]);
self.didReadData(json);
[sock disconnect];
@param sock sock实例
@param err
-(void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err
NSLog(@"%s",__FUNCTION__);
NSLog(@"socketDidDisconnect:%@",[err localizedDescription]);
NSLog(@"socketDidDisconnect:%@",[err localizedFailureReason]);
self.didReadData(nil);
socket=[NSObjectGCDAsyncSocket defaultSocket];
填写发送的数据
socket.writeData=[NSMutableDictionary dictionaryWithDictionary:dictionary];
处理收到的数据
socket.didReadData=^(NSDictionary* didReadData){.......}
[socket startConnect];
添加CocoaAsyncSocket 第三库 链接地址:
优质网站模板GCDAsyncSocket使用方法
目前在使用GCDAsyncSocket的时候,发现只能给服务器发消息,然后服务器返回消息给我。不能主动接受服务器返回消息。后来发现只要在接受服务器的方法里面不停的写一个数据,这样就会在服务器给你发消息的时候接受到。红字部分表示出来的:
-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data
withTag:(long)tag
&&& //关闭菊花
[DejalBezelActivityView removeViewAnimated:YES];
100用来主动接受服务器发送信息
&&& [sock readDataWithTimeout:-1 tag:100];
&&& NSString
*newMessage = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
NSLog(@"%@",newMessage);
实现逻辑就是,我在登陆的时候会[sock readDataWithTimeout:-1
tag:0];一个消息给服务器,服务器返回数据成功,就会触发上面的回调方法,给服务器发送一个 [sock readDataWithTimeout:-1 tag:100];消息。这样一直循环。这个难道就是传说中的发心跳包?暂时不知道这个是什么东西,我对socket不是很了解,说错了,可以指点我一下。
还有我创建socket连接的时候都是会先断开socket
[socket setDelegate:nil
delegateQueue:NULL];
disconnect];这样就保证了,每次只有一个socket连接,我不是做聊天应用的,所以不是很懂这样做有没有必要。还是问问大家有没有什么更好的办法事实接受服务器返回数据。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。GCDAsyncSocket类库,IOS下TCP通讯使用心得 - 推酷
GCDAsyncSocket类库,IOS下TCP通讯使用心得
关于在IOS下使用Socket进行通讯的技术文章也许诺很久了,今日又是一个还债的日子,网上虽然很多介绍过AsyncSocket或GCDAsyncSocket的文章,但其实就那么一两篇大部分都是转载,于是我义正言辞、慷慨激昂的批判他们这种不负责任的态度,学习,不是给自己学的,是要和大家分享的。技术的共享有利于整体行业的进步,也可以使自身更深入全面的了解。
之前的文章中我们讲到过TCP通讯协议,并且也对其进行了较为详细的介绍和描述,关于TCP通讯的原理此处我们不再赘述,如有需要的看官可自行翻阅本人所写的《
正如名称一样GCDAsyncSocket开源类库是以苹果的GCD多任务处理机制完成的一个异步交互套接字通讯。使用方法其实并不复杂,主要说的是在使用这个类库的时候我的一些心得和理解,若有不妥之处望看官指点。首先,每一个GCDAsyncSocket对象(以下简称GCDSocket对象)都可以理解为一个socket套接字,我们的操作都是针对于这个socket执行的各种命令,可以打开一个端口侦听,同样也可以连接其他计算机的端口进行数据通讯等等等等。首先我们来创建一个socket。当然这之前先要将CGDAsyncSocket的.h文件及.m文件加入到我们的项目,并且在需要使用socket连接的地方将.h头文件包含,这些废话我觉得不需要复述了应该(那你还嘚吧嘚的说半天干嘛啊喂!)。具体代码如下
GCDAsyncSocket &socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
代码并不复杂,我们只需要给出一个委托对象也就是第一个参数中的self,以及一个委托运行的GCD队列即可创建一个GCDAsyncSocket,当前代码中我们是使用静态全局函数取得的主消息队列。当然也可以使用其他方法获得其他的GCD队列,比如:dispatch_get_global_queue().
创建了Socket对象我们即可以立即为,当前我们的socket已经进入程序以供操作。但如果你想和服务器进行通讯,那么我们还需要和服务器进行连接。可能有的使用习惯了http协议的人会问,初始化函数中我们为何不直接指定服务器以及端口号?其实这些肯定都是需要的,但是你要理解到,你的socket对象功能不只是可以用来连接服务器,换而言之我们的socket对象一样可以侦听某端口来等待他人连接,所以在通过套接字编程使用TCP协议的时候是我们从http协议过度到TCP协议的一个转变(虽然本文并不会教你如何在IOS上构架服务器。),但并不是第一个,第一个转变是要记得,我们要使用的是协议,并非某个类,所以我上述说明中都是说从http协议过度到TCP而不是跟大家说现在我们将从NSURLRequest和NSURLConnection过度到GCDAsyncSocket。
好了接下来我们看看如何连接服务器。源代码如下:
[socket connectToHost:@“192.168.10.111” onPort@&60000& error:&err];
if (err != nil)
NSLog(@”%@”,err);
代码比前面稍微长了一点,不过实质上完全不复杂,我们只是先声明了一个错误信息的指针,然后使用之前创建的对象调用他的连接方法,第一个参数不难看出是一个IP,第二个参数则是一个端口,如果这里还不理解何为IP和端口的话,就先去看看在开头就提到的我之前写过的那边网络基础篇文章吧…最后一个是出参,如果连接的过程中出现了错误,该方法会把这根指针指向一个具体的错误信息,最后我们再判断一下之前我们创建错误信息的指针是否还是指向空,如果并非指向空那么代表我们连接的过程中出现了错误,将错误信息打印一下吧~不过请切记,此处的错误信息并非你创建连接时所有的错误都会在此处得到反映。
说到这里我们该说一点真正有用的了,GCDAsyncSocket具有一系列完整的委托机制,我们所做的一切处理基本都是异步处理的状态,换句话说,连接之后是否连接成功,连接成功要执行什么懂并非应该写在此处而应该写在相应的委托之中,同样的道理一样适用于发送、读取数据等等。也就是说我们在此处读出的错误只是同步执行的代码处理一些连接时会发生的错误,而更多的处理我们应在相对应的委托中进行处理。首先请看下面这个方法:
-(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port
这个方法就是在成功连接服务器之后的委托方法。关于委托该如何使用我在此处就不赘述了和本文的关系实在不大,不过给诸位看管一个建议,也是我才刚刚纠正的一个编码错误习惯,之前碰到所有委托的地方我都会将直接将当前的类对象设置成委托处理对象,并且遵循委托协议扩充代码,这么做的坏处显而易见,显示层与逻辑层的混淆是一方面,另一方面是一旦需要使用过多的委托,将造成大量不必要的代码都堆积在一个类中,并且我们很容易直接在委托方法中直接使用一些类内成员属性或者甚至是私有成员,而实际上这种做法是很不好的,因为这种最发会使得逻辑出现混乱,处理委托应当是单独处于后台的逻辑,如果需要一些必要的数据传递也应该采取属性侦听、甚至是通知等方式来实现而并非直接在显示层中编写逻辑代码来实现。使得代码耦合性大增的同时也使得很多时候在切换操作对象时对委托对象的处理变得复杂,甚至可能完全相同的代码要难免的复制粘贴。所以我给大家的建议是单独编写一个委托类,在每个类中设置一个该类类型的成员指针,将委托设置到专门的委托对象上去处理,这样不仅效率更高,代码可读性更强,更便于维护,同时也更符合面向对象的编程思想。
回到对GCDAsyncSocket使用的讲解上来,在这个委托方法中,我们可以取到一个socket对象一个服务器IP和一个端口号,你可以处理一切在连接建立之后应该马上执行的事情,比如与服务器进行通信确认连接端以免出现其他人通过IP及端口随意的和你的服务器通信,再比如开启心跳包的发送,让服务器一直可以确认你的存在。不管做什么,都是你和服务器的编写者事前约定好的,就像数据传输格式什么的,如果没有当面约定我坚信他也一定要给你出个文档什么的,否则你的工作接下来将举步维艰。但是不管你要在此处都做什么工作,都要处理哪些事宜,请务必记得,在此处你必须要在函数的最后加上一句:
[socket readDataWithTimeout:-1 tag:0];
这是什么?别慌,按照你看到这个函数的第一反应取理解,没错他就是读取数据的方法,两个参数也略显简单,一个超时时间,如果你设置成-1则认为永不超时,而第二参数则是区别该次读取与其他读取的标志,通常我们在设计视图上的控件时也会有这样的一个属性就是tag。如果你做过web开发,那你应该知道Http标签上的id,如果你做过一些桌面级开发,你的控件或许有个id或者是index再或者是tag的属性来区别这些控件,没错此tag和彼tag功效基本一样。
我们可以这样理解,socket在开启之前是一个巨大门,开启这道门之后(也就是连接之后)就是一个宽敞的通道,通过这条通道所达到的地点就是我们连接的目标服务器,或者是连接过来的客户端,两面都是一样的。我们现在不论是发送数据还是读取数据都是往返于这个大门之中的一个个门卫与邮递员,我们可以把读取数据的方法看作是门卫,而发送数据的人看做是邮递员,没错服务器与客户端都一样,我们都会派出一个个邮递员去我们连接的另一端送信,但是如果你没有命令你的门卫去吧门口邮箱中的信拿过来,那么你的邮递员就会假装看不见邮递员,然后呼呼睡大觉,好吧看起来这些门卫实在没什么责任心不是么,其实他们也是有苦衷的,因为这是最初设计者给他们的命令,不接到命令绝对不要出门,万一收到的是金刚葫芦娃高清全集的种子怎么办!好的就这样,为了避免我们的邮件不被错过,所以建立连接之后就让一个门卫跑去门口等着吧~慢着,万一我需要派出很多个门卫我分不清他们该怎么办,其实他们已经被你分配了工号,这个工号就是tag。
现在我们的连接动作算是完整的做完了,接下来我们要做的就只有两件事,第一个在需要发送数据的时候派出邮递员,以及当门卫接到消息的时候在我们的手机端上根据门卫的消息做出反应。等等,好像少了点什么,没错 少点委托,我们来看一下读取和写入的委托,读取的委托即是门卫接到信息的报告,写入的委托就是邮递员将邮件送完的回复:
-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
-(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag
好的让我们来看看这些委托中我们都能得到什么,首先是读取的委托,是一个socket对象,一个读取到的数据以及一个“门卫的工号”,嗯,大概也就这些,我们还能要什么的,没错这些足够了,别抱怨第二个参数的数据类型,要知道其实最开始接到数据的时候只是字节数组啊,已经给你转换成NSData对象了你就要学会感恩啊,谁让你要用套接字传输了,这就是活该的,所以改怎么读取转换解析这些数据你需要好好的和服务器编写者沟通。除此之外你还要详细的了解如何将NSData转换成各种各样的数据或者文件如果你还不知道该怎么做我这里实在帮不了你,因为我总不能吧多如牛毛的情况都列举在这一篇文章中吧,要知道我每篇文章的篇幅都够长了。。。不过也别因此而气馁百度和谷歌肯定可以帮到你~
接下来我们再看看“邮递员的委托”,嗯一个socket的对象,一个tag嗯,没错,哎哎,慢着,好像哪里不太对啊,我来看看,哪里不对呢,哦对了!发送的数据呢!怎么没有!哎也不对。。。明明是我自己发的数据我还要来干嘛,有了工号我不就知道发送的是什么了么。那是哪里不太对呢。。。哦!是名字!我们的数据传输来说接受可以是读取read而发送通常我们应该写成Send一类的单词,为何这里是Write?写入?没错就是写入,向TCP的通讯流之中写入数据。TCP通讯协议是一个基于字节流的运输层通信协议,其数据传输的形式也是以流的形式提现,而我感觉在使用GCDAsyncSocket的过程中我们可以很好的体会到流的概念,首先来说为什么这种TCP的这种传输形式要叫流而不像UDP中的那样叫做包?流之中又写入和读出的概念,我们可以把整个TCP通讯的连接看作为一条无水的河流,当然因为他没水所以你可以称它为沟,而向其写入数据即是向河流注入水,被写入的数据会向水一样流向连接的另一端。读即是从河流中取水,只要读得动作在继续,并且河流之中有水,那么我们就可以不停的取到数据,不论是河流之中有水你确没有去读亦或者是你去读了而河流之中没有水都会引发看起来完全相同的反应就是没有数据返回,所以在很多时候我们要处理更多的关于接收数据的逻辑的处理。正如我们目前使用的方法就是一种比较粗暴有效的方法——一旦开启连接读取的动作就永不停歇。
接下来我们还要记住使用TCP流式传输数据时的一个关键性问题,数据是不会自己分段的。没错,就如一次次倒入河流中的水一样,数据也同样会向水一样融合为一个整体,换句话说,数据在TCP中传输本身是没有起始或结尾之分,如果我先向数据流中写入两个人的聊天记录,第一句是“你好”,对方回复了一句“不好”,结果发到了服务器,服务器读取出的信息是“你好不好”,同样类似的情况会发生很多,比我举出的这个例子要常见的多比如我先发了一段音频,又发了一段图片,又发了一段文字,最后服务器接收到了一个带语音和字母的静态图片。实际情况上比我说的要遭的多,因为由于字节之间并没有边界,所以字符、文字、音频,我们根本无法确定他们各有多长,胡乱截取,只会导致无法编码解析成图片、文字及音频,所以如何界定数据之间的边界是你开始使用TCP协议之后又一个问题。你可以使用一个固定的字节数组组合来区分开头以及结尾,也可以将所有的字符串都添加一个特殊的界定字符来区分不同的命令与操作。
如果看到这里的看官有心使用GCDAsyncSocket去编写了一个服务器端,并且使用它来接受客户端的数据,比如传输了一些音频,图片等从字节单位看来将会不小的长串数据的话就会发现,服务器端接到的程序是一段一段的,没错,但我没有欺骗你,TCP协议并不会区分你发送数据的头尾,被划分为段知识GCDAsyncSocket为了保证在并不通常的移动互联网之中一样可以安全的传输数据,于是将你所有写入到流的数据都一分割为一段一段的内容,所以请正确理解我在上一段开头所说的“数据是不会自己分段的。”这句话,不要较真哦亲~
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致}

我要回帖

更多关于 ios asyncsocket 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信