iOS Socket-TCP
2017-08-03 本文已影响98人
等这姑娘老在我心里
demo 地址 https://github.com/Liuchunqi3240/demo/tree/master/iOS_Socket/TCP
0x01 Server端
server端使用CocoaAsyncSocket 完成
pod 'CocoaAsyncSocket'
#import "GCDAsyncSocket.h"
@interface ViewController ()<GCDAsyncSocketDelegate>
@end
@implementation ViewController{
GCDAsyncSocket *_serverSocket;
dispatch_queue_t _golbalQueue;
NSMutableArray *_clientSocket;
}
初始化 server
- (void)initServer{
if (!_serverSocket) {
_clientSocket = [NSMutableArray array];
_golbalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
_serverSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:_golbalQueue];
}
NSLog(@"server inited");
}
开启服务
//启动sever
- (void)startChatServer{
NSError *error;
//开启一个可接受的ip(本机ip 注意:模拟器获取不到Ip) 和 端口
[_serverSocket acceptOnInterface:@"192.168.50.128" port:2333 error:&error];
if (error) {
NSLog(@"服务器开启失败 error is %@",error);
}else{
NSLog(@"服务器开启成功");
//最重要的来了,开启后台模式,要不然退到后台,再回来就不管用了
[_serverSocket enableBackgroundingOnSocket];
}
}
接收客户端链接
#pragma mark 有客户端建立连接的时候调用
-(void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket{
NSLog(@"new clientSocket Ip is %@",newSocket.connectedHost);
[_clientSocket addObject:newSocket];
//newSocket为客户端的Socket。这里读取数据
[newSocket readDataWithTimeout:-1 tag:100];
}
给客户端回消息
[sock writeData:[@"message ..." dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0];
#pragma mark - GCDAsyncSocketDelegate
-(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag{
[sock readDataWithTimeout:-1 tag:100];
}
收到客户端发来的消息
#pragma mark - GCDAsyncSocketDelegate
-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
//接收到数据
NSString *receiverStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"服务端收到的数据:%@",receiverStr);
[sock writeData:[@"mes received" dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0];
}
0x02 客户端 (Client)
client 端使用原生sdk编写
@interface ViewController ()<NSStreamDelegate>
@property (weak, nonatomic) IBOutlet UITextField *mesTextField;
@end
@implementation ViewController{
NSInputStream *_inputStream;
NSOutputStream *_outputStream;
}
连接到server
- (void)connectServer{
NSString *host = @"192.168.50.128";
int port = 2333;
//创建输入输出流
CFReadStreamRef readStreamRef;
CFWriteStreamRef writeStreamRef;
CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)host, port, &readStreamRef, &writeStreamRef);
_inputStream = (__bridge NSInputStream *)(readStreamRef);
_outputStream = (__bridge NSOutputStream *)(writeStreamRef);
_inputStream.delegate = self;
_outputStream.delegate = self;
// 输入输出流必须加入主运行runLoop中
[_inputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
[_outputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
[_inputStream open];
[_outputStream open];
}
给服务端发送消息
- (IBAction)sendMes:(id)sender {
NSString *msg = self.mesTextField.text;
NSData *msgData = [msg dataUsingEncoding:NSUTF8StringEncoding];
[_outputStream write:msgData.bytes maxLength:msgData.length];
self.mesTextField.text = @"";
NSLog(@"客户端发送消息:%@",msg);
}
NSStreamDelegate
#pragma MARK - NSStreamDelegate
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode{
switch(eventCode) {
case NSStreamEventOpenCompleted:
NSLog(@"客户端输入输出流打开完成");
break;
case NSStreamEventHasBytesAvailable:
NSLog(@"客户端有字节可读");
//读取服务端发来的消息
[self readData];
break;
case NSStreamEventHasSpaceAvailable:
NSLog(@"客户端可以发送字节");
break;
case NSStreamEventErrorOccurred:
NSLog(@"客户端连接出现错误");
break;
case NSStreamEventEndEncountered:
NSLog(@"客户端连接结束");
//关闭输入输出流
[_inputStream close];
[_outputStream close];
//从主运行循环移除
[_inputStream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
[_outputStream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
break;
default:
break;
}
}
读取服务端返回的消息
-(void)readData{
//建立一个缓冲区 可以放1024个字节
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(@"Socket:读取从服务端发来的消息:%@",recStr);
}