用socket從服務器上獲取數(shù)據(jù)楞泼,有以下三種方法:
第一種是使用封裝好的第三方GCDAsyncSocket抢腐,下載地址是https://github.com/Yuzeyang/GCDAsyncSocketManager
未斑,在網(wǎng)上可以搜到它的使用方法(有很多)。
第二種是使用系統(tǒng)自帶的方法,代碼如下
#import "SocketManager.h"
@interface SocketManager ()<NSStreamDelegate>
{
NSInputStream *inputStream;
NSOutputStream *outputStream;
}
@end
@implementation SocketManager
+ (instancetype)sharedSocketManager {
static SocketManager *socketManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
socketManager = [[SocketManager alloc] init];
});
return socketManager;
}
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode{
NSLog(@"eventCode:%lu",(unsigned long)eventCode);
switch (eventCode) {
case NSStreamEventOpenCompleted:
NSLog(@"輸入輸出流打開完成");
break;
case NSStreamEventHasBytesAvailable:
NSLog(@"有字節(jié)可讀");
[self readData];
break;
case NSStreamEventHasSpaceAvailable:
NSLog(@"可以發(fā)送字節(jié)");
break;
case NSStreamEventErrorOccurred:
NSLog(@" 連接出現(xiàn)錯誤");
break;
case NSStreamEventEndEncountered:
NSLog(@"連接結束");
// 關閉輸入輸出流
[inputStream close];
[outputStream close];
// 從主運行循環(huán)移除
[inputStream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
break;
default:
break;
}
}
- (void)connect{
NSString *host = IP地址;
int port = 端口號;
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)host, port, &readStream, &writeStream);
inputStream = (__bridge NSInputStream *)(readStream);
outputStream = (__bridge NSOutputStream *)(writeStream);
inputStream.delegate = self;
outputStream.delegate = self;
[inputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
[inputStream open];
[outputStream open];
}
- (void)login{
寫入的命令,此處省略
[outputStream write:data.bytes maxLength:data.length];
}
- (void)readData{
uint8_t buf[1024];
NSInteger len = [inputStream read:buf maxLength:sizeof(buf)];
NSData *data = [NSData dataWithBytes:buf length:len];
NSString *recStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@",recStr);
// [self cleanUpStream:inputStream];
}
- (void)cleanUpStream:(NSStream *)stream
{
[stream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[stream close];
stream = nil;
}
@end
第三種方法是使用socket編程最底層的connect等方法甩鳄,參考地址:http://blog.csdn.net/majiakun1/article/details/19357415
,代碼如下:
#import "SocketManager1.h"
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <syslog.h>
#include <errno.h>
#include <stdlib.h>
@implementation SocketManager1
- (void)socketConnect:(NSString *)host Port:(int)port{
const char *ip = IP地址;
self.socketFD = socket(AF_INET, SOCK_STREAM, 0);
NSData *dataLogin = [self login];
NSInteger bytes = [dataLogin length];
NSLog(@"socketFD:%d",self.socketFD);
struct sockaddr_in nativeAdd;
nativeAdd.sin_len = sizeof(struct sockaddr);
nativeAdd.sin_family = AF_INET;
nativeAdd.sin_port = htons(port);
nativeAdd.sin_addr.s_addr = inet_addr(ip);
self.status = connect(self.socketFD, (struct sockaddr *) &nativeAdd, sizeof(nativeAdd));
if (-1 == self.status) {
close(self.socketFD);
}
if (self.status <0) {
NSLog(@"連接失敗:%d",errno);
}else{
NSLog(@"連接成功:%d",self.status);
self.status = write(self.socketFD, [dataLogin bytes], bytes);
if (self.status <0) {
NSLog(@"寫入失敗:%d",errno);
}else{
NSLog(@"登陸成功:%d",self.status);
[self read];
}
}
}
- (void)read{
[NSThread detachNewThreadSelector:@selector(thread:) toTarget:self withObject:@"thread1"];
}
- (void)thread:(NSString *)sender{
NSThread *thread = [NSThread currentThread];
NSLog(@"%@",thread);
NSMutableData *data = [[NSMutableData alloc]init];
BOOL waitingForData = YES;
int i = 0;
do {
const char *buffer[10000];
int length = sizeof(buffer);
int result = read(self.socketFD, &buffer, length);
NSLog(@"result:%d",result);
if (result >0) {
[data appendBytes:buffer length:result];
NSLog(@"data:%@",data);
}else{
NSString *string = [[NSString alloc]initWithData:data encoding:NSASCIIStringEncoding];
NSLog(@"string:%@",string);
waitingForData = NO;
}
++i;
NSLog(@"i:%d",i);
NSLog(@"waitingForData:%d",waitingForData);
} while (waitingForData == YES);
}
- (NSData *)login{
寫入的命令额划,此處省略妙啃;
return data;
}
注:服務器狀態(tài)碼
1XX - 服務器的信息
2XX - 表示請求成功
200:請求成功
201:成功創(chuàng)建連接
202:接受請求
3XX - 表示重定向
302:表示重定向
304:表示服務端資源沒有變化,訪問緩存
問題 - 這次請求沒有真正低訪問服務器端
305:使用代理
4XX - 客戶端錯誤
400:錯誤的請求
404:網(wǎng)頁找不到
403:拒絕訪問
405:請求類型不允許
5XX - 服務端錯誤
500:服務端錯誤
502:路徑錯誤
504:請求超時
505:http版本不支持