实现socket的监听方法
(1)
使用
C
语言实现,
(2)
使用
CocoaAsyncSocket
第三方框,内部是对
C
的封装
https://github.com/robbiehanson/CocoaAsyncSocket
Telnet
命令
telnet host port/telnet 192.168.10.10 5288
1.
telnet
命令是连接
服务器上的某个端口对应的服务
案列:10086服务
类似的客户端演示:
编写代码:
//
// main.m
#import <Foundation/Foundation.h>
#import "ServiceListener.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
// 1.创建一个服务监听对象
ServiceListener *listener = [[ServiceListener alloc] init];
// 2.开始监听
[listener start];
// 3.开启主运行循环,让服务不能停
[[NSRunLoop mainRunLoop] run];
}
return 0;
}
//
// ServiceListener.h
// 服务监听者
#import <Foundation/Foundation.h>
@interface ServiceListener : NSObject
/**
* 开启服务
*/
- (void)start;
@end
//
// ServiceListener.m
#import "ServiceListener.h"
#import "GCDAsyncSocket.h"
@interface ServiceListener() <GCDAsyncSocketDelegate>
/**
* 服务器端的socket对象
*/
@property(nonatomic,strong)GCDAsyncSocket *serviceScoket;
/**
* 保存所有客户端的socket对象的数组
*/
@property(nonatomic,strong)NSMutableArray *clientSockets;
@end
@implementation ServiceListener
- (NSMutableArray *)clientSockets
{
if (!_clientSockets) {
_clientSockets = [NSMutableArray array];
}
return _clientSockets;
}
/**
* 开启10086服务
*/
- (void)start
{
// 1.创建一个socket对象
// serviceScoket: 服务端的scoket只监听有没有客户端请求连接
GCDAsyncSocket *serviceScoket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(0, 0)];
self.serviceScoket = serviceScoket;
// 2.绑定端口,并开启监听
// 代表10086服务以及启动
NSError *error = nil;
[serviceScoket acceptOnPort:5288 error:&error];
if (!error) {
NSLog(@"10086服务开启成功");
}else{
NSLog(@"10086服务开启失败%@",error);
}
}
#pragma mark - <GCDAsyncSocketDelegate>
/**
* 有客户端的socket连接到服务器就会调用这个方法
*
* @param sock 服务器端的socket
* @param newSocket 客户端的socket
*/
- (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket
{
// 1.保存客户端的socket
[self.clientSockets addObject:newSocket];
// 3.提供服务
NSMutableString *serviceStr = [NSMutableString string];
[serviceStr appendString:@"欢迎来到10086的在线服务,请输入下面的数组选择服务\n"];
[serviceStr appendString:@"[0]在线充值\n"];
[serviceStr appendString:@"[1]在线投诉\n"];
[serviceStr appendString:@"[2]优惠信息\n"];
[serviceStr appendString:@"[3]特殊服务\n"];
[serviceStr appendString:@"[4]退出\n"];
NSData *data = [serviceStr dataUsingEncoding:NSUTF8StringEncoding];
[newSocket writeData:data withTimeout:-1 tag:0];
// 2.监听客户端有没有数据上传
// timeout -1:代表不超时
// tag 标识:现在不用就写0
[newSocket readDataWithTimeout:-1 tag:0];
}
/**
* 读取客户端请求的数据
*
* @param sock 客户端的socket
* @param data 二进制数据
* @param tag 标识
*/
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
// 1.把NSData转成NSString
NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
// 2.处理请求
NSInteger code = [str integerValue];
NSString *responseStr = nil;
switch (code) {
case 0:
responseStr = @"充值服务暂停中...\n";
break;
case 1:
responseStr = @"投诉服务暂停中...\n";
break;
case 2:
responseStr = @"优惠信息没有...\n";
break;
case 3:
responseStr = @"怎么可能有特殊服务...\n";
break;
case 4:
responseStr = @"退出成功\n";
break;
}
// 3.返回数据给客户端
NSData *responseData = [responseStr dataUsingEncoding:NSUTF8StringEncoding];
[sock writeData:responseData withTimeout:-1 tag:0];
// 4.移除客户端
if (code == 4) {
[self.clientSockets removeObject:sock];
}
#warning 每次读完数据后,都要调用一次监听数据的方法(CocoaAsyncSocket框架是这样设计的)
[sock readDataWithTimeout:-1 tag:0];
}
@end
演示: