实现socket的监听方法
- 使用c语言
- 使用CocoaAsyncSocket框架(内部对C的封装)
下载
1.创建命令行工程
2.集成CocoaAsyncSocket
如果您已经熟练使用CocoaPods,请忽略此点
1.导入框架文件
如果编译出现
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_GCDAsyncSocket", referenced from:
objc-class-ref in LKLScoketService.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
解决办法
自定义socket服务对象
.h文件
#import <Foundation/Foundation.h>
#import "GCDAsyncSocket.h"
@interface LKLSocketService : NSObject
//开启服务
- (void)start;
@end
.m文件
#import "LKLSocketService"
@interface LKLSocketService ()<GCDAsyncSocketDelegate>
@property (strong, nonatomic) GCDAsyncSocket *socket;
@property (strong, nonatomic) NSMutableArray *clientSockets;//保存客户端scoket
@end
@implementation LKLSocketService
- (NSMutableArray *)clientSockets
{
if (_clientSockets == nil) {
_clientSockets = [[NSMutableArray alloc]init];
}
return _clientSockets;
}
- (void)start
{
//1.创建scoket对象
GCDAsyncSocket *serviceScoket = [[GCDAsyncSocket alloc]initWithDelegate:self delegateQueue:dispatch_get_global_queue(0, 0)];
//2.绑定端口(5288)
//端口任意,但遵循有效端口原则范围:0~65535,其中0~1024由系统使用或者保留端口,开发中建议使用1024以上的端口
NSError *error = nil;
[serviceScoket acceptOnPort:5288 error:&error];
//3.开启服务(实质第二步绑定端口的同时默认开启服务)
if (error == nil)
{
NSLog(@"开启成功");
}
else
{
NSLog(@"开启失败");
}
self.socket = serviceScoket;
}
#pragma mark GCDAsyncSocketDelegate
//连接到客户端socket
- (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket
{
//sock 服务端的socket
//newSocket 客户端连接的socket
NSLog(@"%@----%@",sock, newSocket);
//1.保存连接的客户端socket(否则newSocket释放掉后链接会自动断开)
[self.clientSockets addObject:newSocket];
//连接成功服务端立即向客户端提供服务
NSMutableString *serviceContent = [NSMutableString string];
[serviceContent appendString:@"话费查询请按1\n"];
[serviceContent appendString:@"话费充值请按2\n"];
[serviceContent appendString:@"投诉建议请按3\n"];
[serviceContent appendString:@"最新优惠请按4\n"];
[serviceContent appendString:@"人工服务请按0\n"];
[newSocket writeData:[serviceContent dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0];
//2.监听客户端有没有数据上传
//-1代表不超时
//tag标示作用
[newSocket readDataWithTimeout:-1 tag:0];
}
//接收到客户端数据
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
//1.接受到用户数据
NSString *str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSInteger code = [str integerValue];
NSString *responseString = nil;
switch (code) {
case 1:
responseString = @"您的账户余额为0,请尽快充值\n";
break;
case 2:
responseString = @"系统忙,请稍后重试\n";
break;
case 3:
responseString = @"系统忙,暂时不能接受投诉建议\n";
break;
case 4:
responseString = @"请上官网查看更多优惠\n";
break;
case 0:
responseString = @"客服忙,谢谢!\n";
break;
default:
break;
}
//处理请求 返回数据
[sock writeData:[responseString dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0];
if (code == 0) {
[self.clientSockets removeObject:sock];
}
//CocoaAsyncSocket每次读取完成后必须调用一次监听数据方法
[sock readDataWithTimeout:-1 tag:0];
}
开始Socket服务
main.m文件
#import <Foundation/Foundation.h>
#import "LKLSocketService.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSLog(@"Hello, World!");
//创建服务对象
LKLSocketService *socketSerview = [[LKLSocketService alloc]init];
//开始服务
[socketSerview start];
//循环运行
[[NSRunLoop mainRunLoop]run];//目的让服务器不停止
}
return 0;
}
终端模拟客户端
使用Telnet命令telnet host port/telnet 192.168.10.10 5288
telnet命令是连接服务器上的某个端口对应的服务
-
通信
Connection closed by foreign host.//断开连接