TCP傳輸協(xié)議:前2個子節(jié)為一個固定的字符夺英,這里以0x809B為例痛悯,接著為4個子節(jié)(存放content的長度)载萌,然后為傳輸?shù)膬?nèi)容content
以下內(nèi)容都在Demo中扭仁,有興趣可以下載
一、 拼接方式1---使用Byte數(shù)組
這里以傳輸一張圖片為例
1.1前期準(zhǔn)備---獲取一張圖片的大小
NSString *path= [[NSBundle mainBundle] pathForResource:@"ceshi" ofType:@"jpeg"];
NSData* content = [NSData dataWithContentsOfFile:path];
int value = (int)content.length;
1.2 將長度value轉(zhuǎn)換為4個字節(jié)
Byte byteData[4] = {};
byteData[0] =(Byte)((value & 0xFF000000)>>24);
byteData[1] =(Byte)((value & 0x00FF0000)>>16);
byteData[2] =(Byte)((value & 0x0000FF00)>>8);
byteData[3] =(Byte)((value & 0x000000FF));
//轉(zhuǎn)換為4個字節(jié)
1.3 拼接固定字符并轉(zhuǎn)為NSData
Byte byte[] = {0x80,0x9B,byteData[0],byteData[1],byteData[2],byteData[3]};
NSData *temphead = [[NSData alloc]initWithBytes:byte length:6];
1.4 拼接傳輸?shù)臄?shù)據(jù)(圖片)
//拼接content
NSMutableData *m_data = [[NSMutableData alloc] init];
[m_data appendData:temphead];
[m_data appendData:content];
二、 拼接方式2---使用十六進(jìn)制轉(zhuǎn)換
2.1前期準(zhǔn)備---獲取一張圖片的大小
NSString *path= [[NSBundle mainBundle] pathForResource:@"ceshi" ofType:@"jpeg"];
NSData* content = [NSData dataWithContentsOfFile:path];
int value = (int)content.length;
2.2 將長度value轉(zhuǎn)換十六進(jìn)制string
//將長度轉(zhuǎn)為十進(jìn)制string
NSString* decimalString = [NSString stringWithFormat:@"%d",value];
//將十進(jìn)制string轉(zhuǎn)為十六進(jìn)制并保證長度為8
NSString* firstHex = [decimalString decimalToHexWithLength:8];//私有方法(見Demo)
2.3 將十六進(jìn)拼接固定字符并轉(zhuǎn)為NSData
//將十六進(jìn)制拼接上809B
NSString* hexString = [NSString stringWithFormat:@"809B%@",firstHex];
//將十六進(jìn)制轉(zhuǎn)為NSData
NSData* temphead = [hexString convertBytesStringToData];
2.4 拼接傳輸?shù)臄?shù)據(jù)(圖片)
//拼接content
NSMutableData *m_data = [[NSMutableData alloc] init];
[m_data appendData:temphead];
[m_data appendData:content];
三仰迁、 解析數(shù)據(jù)
這里是模擬服務(wù)器返回的數(shù)據(jù)
因?yàn)榘l(fā)送給服務(wù)器內(nèi)容的格式根服務(wù)器返回的內(nèi)容的格式相同徐许,所以這里我們直接解析我們發(fā)送給服務(wù)器的數(shù)據(jù)就可以
3.1 獲取頭部數(shù)據(jù)
NSData *head = [_receiveData subdataWithRange:NSMakeRange(0, 6)];//取得頭部數(shù)據(jù)
NSData *lengthData = [head subdataWithRange:NSMakeRange(2, 4)];//取得長度數(shù)據(jù)
3.2 將4個字節(jié)的數(shù)據(jù)還原為content的長度
1 將lengthData轉(zhuǎn)為16進(jìn)制數(shù)
NSString* hexString = [lengthData convertDataToHexStr];
2 將16進(jìn)制數(shù)轉(zhuǎn)為10進(jìn)制
NSInteger length = [[hexString hexToDecimal]integerValue];//得出content長度
3.3 取出content的內(nèi)容
NSInteger complateDataLength = length + 6;//算出一個包完整的長度(內(nèi)容長度+頭長度)
if (_receiveData.length >= complateDataLength)//如果緩存中數(shù)據(jù)夠一個整包的長度
{
//這個data即為我們傳出去的數(shù)據(jù)
NSData *data = [_receiveData subdataWithRange:NSMakeRange(6, length)];//截取一個包的長度(處理粘包)
//顯示到程序上
[self.resultImage setImage:[UIImage imageWithData:data]];
}
四、 進(jìn)制缸沃、Byte和泌、Byte數(shù)組、NSData的相互轉(zhuǎn)換(參考Demo)
#import "NSString+SwitchData.h"
@implementation NSString (SwitchData)
/**
帶子節(jié)的string轉(zhuǎn)為NSData
@return NSData類型
*/
-(NSData*) convertBytesStringToData {
NSMutableData* data = [NSMutableData data];
int idx;
for (idx = 0; idx+2 <= self.length; idx+=2) {
NSRange range = NSMakeRange(idx, 2);
NSString* hexStr = [self substringWithRange:range];
NSScanner* scanner = [NSScanner scannerWithString:hexStr];
unsigned int intValue;
[scanner scanHexInt:&intValue];
[data appendBytes:&intValue length:1];
}
return data;
}
/**
十進(jìn)制轉(zhuǎn)十六進(jìn)制
@return 十六進(jìn)制字符串
*/
- (NSString *)decimalToHex {
long long int tmpid = [self intValue];
NSString *nLetterValue;
NSString *str = @"";
long long int ttmpig;
for (int i = 0; i < 9; i++) {
ttmpig = tmpid % 16;
tmpid = tmpid / 16;
switch (ttmpig) {
case 10:
nLetterValue = @"A";
break;
case 11:
nLetterValue = @"B";
break;
case 12:
nLetterValue = @"C";
break;
case 13:
nLetterValue = @"D";
break;
case 14:
nLetterValue = @"E";
break;
case 15:
nLetterValue = @"F";
break;
default:
nLetterValue = [[NSString alloc]initWithFormat:@"%lli", ttmpig];
}
str = [nLetterValue stringByAppendingString:str];
if (tmpid == 0) {
break;
}
}
return str;
}
/**
十進(jìn)制轉(zhuǎn)十六進(jìn)制
length 總長度,不足補(bǔ)0
@return 十六進(jìn)制字符串
*/
- (NSString *)decimalToHexWithLength:(NSUInteger)length{
NSString* subString = [self decimalToHex];
NSUInteger moreL = length - subString.length;
if (moreL>0) {
for (int i = 0; i<moreL; i++) {
subString = [NSString stringWithFormat:@"0%@",subString];
}
}
return subString;
}
/**
十六進(jìn)制轉(zhuǎn)十進(jìn)制
@return 十進(jìn)制字符串
*/
- (NSString *)hexToDecimal {
return [NSString stringWithFormat:@"%lu",strtoul([self UTF8String],0,16)];
}
/*
二進(jìn)制轉(zhuǎn)十進(jìn)制
@return 十進(jìn)制字符串
*/
- (NSString *)binaryToDecimal {
int ll = 0 ;
int temp = 0 ;
for (int i = 0; i < self.length; i ++) {
temp = [[self substringWithRange:NSMakeRange(i, 1)] intValue];
temp = temp * powf(2, self.length - i - 1);
ll += temp;
}
NSString * result = [NSString stringWithFormat:@"%d",ll];
return result;
}
/**
十進(jìn)制轉(zhuǎn)二進(jìn)制
@return 二進(jìn)制字符串
*/
- (NSString *)decimalToBinary {
NSInteger num = [self integerValue];
NSInteger remainder = 0; //余數(shù)
NSInteger divisor = 0; //除數(shù)
NSString * prepare = @"";
while (true) {
remainder = num%2;
divisor = num/2;
num = divisor;
prepare = [prepare stringByAppendingFormat:@"%d",(int)remainder];
if (divisor == 0) {
break;
}
}
NSString * result = @"";
for (NSInteger i = prepare.length - 1; i >= 0; i --) {
result = [result stringByAppendingFormat:@"%@",
[prepare substringWithRange:NSMakeRange(i , 1)]];
}
return [NSString stringWithFormat:@"%08d",[result intValue]];
}
@end
@implementation NSData (SwitchData)
/**
NSData 轉(zhuǎn) 十六進(jìn)制string
@return NSString類型的十六進(jìn)制string
*/
- (NSString *)convertDataToHexStr{
if (!self || [self length] == 0) {
return @"";
}
NSMutableString *string = [[NSMutableString alloc] initWithCapacity:[self length]];
[self enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange, BOOL *stop) {
unsigned char *dataBytes = (unsigned char*)bytes;
for (NSInteger i = 0; i < byteRange.length; i++) {
NSString *hexStr = [NSString stringWithFormat:@"%x", (dataBytes[i]) & 0xff];
if ([hexStr length] == 2) {
[string appendString:hexStr];
} else {
[string appendFormat:@"0%@", hexStr];
}
}
}];
return string;
}
/**
NSData 轉(zhuǎn) NSString
@return NSString類型的字符串
*/
- (NSString *)dataToString {
Byte *bytes = (Byte *)[self bytes];
NSMutableString *string = [[NSMutableString alloc] init];
for(int i = 0; i< [self length]; i++) {
if (i == 0) {
[string appendString:[NSString stringWithFormat:@"%hhu",bytes[i]]];
}else {
[string appendString:[NSString stringWithFormat:@",%hhu",bytes[i]]];
}
}
return string;
}
@end
寫在最后:
希望這篇文章對您有幫助。當(dāng)然如果您發(fā)現(xiàn)有可以優(yōu)化的地方属提,希望您能慷慨的提出來冤议。最后祝您工作愉快师坎!