NSStream实现TCP Socket客户端,与硬件直接做交互

网络由下往上分为:

物理层、数据链路层、网络层、传输层、会话层、表示层和应用层

其中IP协议对应于网络层,TCP协议协议对应传输层,HTTP协议对应应用层

TCP连接三次握手:

第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。

利用Socket建立网络连接的步骤:服务器监听,客户端请求,连接确认

  1、服务器监听:服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求。
  2、客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。
  为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
  3、连接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,双方就正式建立连接。

NSStream使用详解

属性设置,输入输出流

@property (nonatomic, retain) NSInputStream *inputStream;
@property (nonatomic, retain) NSOutputStream *outputStream;

初始化输入输出流,建立连接

CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL,(bridge CFStringRef)[USER_DEFAULT objectForKey:@”ipAddress”], [[USER_DEFAULT objectForKey:@”port”] intValue], &readStream, &writeStream);
_inputStream = (
bridge_transfer NSInputStream )readStream;
_outputStream = (__bridge_transfer NSOutputStream
)writeStream;
[_inputStream setDelegate:self];
[_outputStream setDelegate:self];
[_inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[_outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[_inputStream open];
[_outputStream open];

NSStream代理方法

-(void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent;

streamEvent连接状态说明

typedef NS_OPTIONS(NSUInteger, NSStreamEvent) {
NSStreamEventNone = 0,//无状态
NSStreamEventOpenCompleted = 1UL << 0,//输入输出流打开成功
NSStreamEventHasBytesAvailable = 1UL << 1,//收到数据,有字节可读
NSStreamEventHasSpaceAvailable = 1UL << 2,//可以发送字节
NSStreamEventErrorOccurred = 1UL << 3,//连接出现错误
NSStreamEventEndEncountered = 1UL << 4//连接结束
};

有字节可读,收到数据处理(一般为16进制数据)

NSMutableData *input = [[NSMutableData alloc] init];
uint8_t buffer[1024];  //①
int len;
while([_inputStream hasBytesAvailable]) //②
{
    len = [_inputStream read:buffer maxLength:sizeof(buffer)];  //③
    if (len > 0)
    {
        [input appendBytes:buffer length:len];
    }
}
//将收到的流数据转换为字符串
NSString *resultstring = @"";
Byte *bytes = (Byte *)[input bytes];
for(int i=0;i<[input length];i++)
{
    NSString *newHexStr = [NSString stringWithFormat:@"%x",bytes[i]&0xff]; ///16进制数
    if([newHexStr length]==1)
        resultstring = [NSString stringWithFormat:@"%@0%@",resultstring,newHexStr];
    else
        resultstring = [NSString stringWithFormat:@"%@%@",resultstring,newHexStr];
}
NSLog(@"接收:%@",resultstring);

发送数据包到接收端

//将发送的字符串转换为data数据(需转为16进制字符串)
NSData *data = [NSData data];
[_outputStream write:[data bytes] maxLength:data.length];

断开连接

[_outputStream close];
[_outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[_outputStream setDelegate:nil];
[_inputStream close];
[_inputStream removeFromRunLoop:[NSRunLoop currentRunLoop]forMode:NSDefaultRunLoopMode];
[_inputStream setDelegate:nil];

普通字符串与16进制字符串互相转换

普通字符串转16进制字符串

+ (NSString *)hexStringFromString:(NSString *)string{
    NSData *myD = [string dataUsingEncoding:NSUTF8StringEncoding];
    Byte *bytes = (Byte *)[myD bytes];
    //下面是Byte 转换为16进制。
    NSString *hexStr=@"";
    for(int i=0;i < [myD length];i++)
    {
        NSString *newHexStr = [NSString stringWithFormat:@"%x",bytes[i]&0xff];///16进制数

        if([newHexStr length]==1)

            hexStr = [NSString stringWithFormat:@"%@0%@",hexStr,newHexStr];

        else 

            hexStr = [NSString stringWithFormat:@"%@%@",hexStr,newHexStr]; 
    } 
    return hexStr; 
}

16进制字符串转换为普通字符串

+ (NSString *)stringFromHexString:(NSString *)hexString {
    char *myBuffer = (char *)malloc((int)[hexString length] / 2 + 1);
    bzero(myBuffer, [hexString length] / 2 + 1);
    for (int i = 0; i < [hexString length] - 1; i += 2) {
        unsigned int anInt;
        NSString * hexCharStr = [hexString substringWithRange:NSMakeRange(i, 2)];
        NSScanner * scanner = [[NSScanner alloc] initWithString:hexCharStr];
        [scanner scanHexInt:&anInt];
        myBuffer[i / 2] = (char)anInt;
    }
    NSString *unicodeString = [NSString stringWithCString:myBuffer encoding:4];
    return unicodeString;
}    

NSString转换为NSData

+ (NSData*) hexToBytesWIthStringxx:(NSString *)str {
NSMutableData* data = [NSMutableData data];
int idx;
for (idx = 0; idx+2 <= str.length; idx+=2) {
    NSRange range = NSMakeRange(idx, 2);
    NSScanner* scanner = [NSScanner scannerWithString:hexStr];
    unsigned int intValue;
    [scanner scanHexInt: &intValue];
    [data appendBytes: &intValue length:1];
}
return data;
}
文章目录
  1. 1. TCP连接三次握手:
  2. 2. 利用Socket建立网络连接的步骤:服务器监听,客户端请求,连接确认
  • NSStream使用详解
    1. 1. 属性设置,输入输出流
    2. 2. 初始化输入输出流,建立连接
    3. 3. NSStream代理方法
      1. 3.1. streamEvent连接状态说明
      2. 3.2. 有字节可读,收到数据处理(一般为16进制数据)
    4. 4. 发送数据包到接收端
    5. 5. 断开连接
  • 普通字符串与16进制字符串互相转换
    1. 1. 普通字符串转16进制字符串
    2. 2. 16进制字符串转换为普通字符串
    3. 3. NSString转换为NSData
  • ,