Socket的简单使用

爱⌒轻易说出口 提交于 2019-12-30 00:41:30

一.Socket:

  • Socket又称”套接字"
  • 网络上的两个程序通过一个双向的通信链接实现数据的交换,这个连接的一端成为一个socket
  • 应用程序通常通过”套接字”向网络发出请求或者应答网络请


 

二.网络通信的要素

  • 网络上的请求就是通过socket来建立链接然后互相通信
  • ip地址(网络上主机设备的唯一标识)
  • 端口号(定位程序)

         用于标示进程的逻辑地址,不同进程的标示

         有效端口:0~65535,其中0~1024由系统使用或者保留端口,开发中建议使用1024以上的端口

  • 传输协议
        通信的规则-->常见协议:TCP  UDP
 

 三.TCP和UDP
TCP(传输控制协议)
  • 建立链接,形成传输数据的通道
  • 在链接中进行打暑假传输(数据不受到限制 )
  • 通过三次握手完成链接,是可靠协议,安全送达
  • 必须建立链接,效率会稍低
UDP(用户数据报协议)
  • 将数据及源和目的封装成数据包中,不需要建立链接
  • 每个数据报的大小限制在64k之内
  • 因为无需链接,因此是不可靠协议
  • 不需要建立链接,速度快

 


 

四.Socket通信流程图


 

五.实现Socket服务端监听

  • 实现socket的方法
        1.使用c语言实现
        2.使用cocoaAsyncSocket(OC)第三方框架,内部是对C的封装
  • Telnet命令
        telnet host port/telnet --> 192.168.10.10 5288
       1.telnet命令是链接服务器上的某个端口对应的服务
       2.host :  系统偏好-->网络-->IP
       3.host:   有效端口:0~65535,其中0~1024由系统使用或者保留端口,开发中建议使用1024以上的端口
 

六.代码的简单实现
  • 添加第三方框架cocoaAsyncSocket--->下载地址  https://github.com/robbiehanson/CocoaAsyncSocket
  • 创建工程: 从第三方框架中拉入 GCDAsyncSocket.h  GCDAsyncSocket.m

  • 创建服务监听对象
#import "ServiceListen.h"
//引入头文件
#import "GCDAsyncSocket.h"
@interface ServiceListen()<GCDAsyncSocketDelegate>
//服务端对象
@property(nonatomic,strong)GCDAsyncSocket *serverSocket;
//保存客户端对象
@property(nonatomic,strong)NSMutableArray *NewSockets;//客户端socket对象

@end
@implementation ServiceListen
/**
 *  懒加载
 */
-(NSMutableArray *)NewSockets
{
    if (_NewSockets==nil) {
        _NewSockets=[NSMutableArray new];
    }
    return _NewSockets;
}
/**
 *  开启服务方法的实现
 */
-(void)start{
    //开启10086服务
    //服务端的socket只监听 有没客户端请求链接
    GCDAsyncSocket *serverSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(0, 0)];
       //绑定端口,并开启监听,代表10086服务已经开启
    NSError *error=nil;
    [serverSocket acceptOnPort:5288 error:&error];
    if (!error) {
        NSLog(@"10086服务开启成功");
    }
    else
    {
        NSLog(@"开启失败%@",error);
    }
    self.serverSocket=serverSocket;

}

#pragma mark  有客户端socket链接到服务器
/**
 *  有客户端socket链接到服务器调用
 *
 *  @param sock      服务端
 *  @param newSocket 客户端
 */
-(void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket
{
    NSLog(@"服务端serverSocket  %@",sock);
    NSLog(@"客户端newSocket   %@",newSocket);
    //保存客户端的socket
    [self.NewSockets addObject:newSocket];
    //提供服务
    NSMutableString *serverStr = [NSMutableString string];
    [serverStr appendString:@"欢迎光临!!!请输入下面的数字选择服务!\n"];
    [serverStr appendString:@"[0]在线充值\n"];
    [serverStr appendString:@"[1]在线投诉\n"];
    [serverStr appendString:@"[2]优惠信息\n"];
    [serverStr appendString:@"[3]特殊服务\n"];
    [serverStr appendString:@"[4]退出\n"];
    [newSocket writeData:[serverStr dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0];
    
    //监听客户端有没有数据上传
    //Timeout:-1 代表不超时
    //tag:标识作用,现在不用
    [newSocket readDataWithTimeout:-1 tag:0];
}
#pragma mark 读取客户端的请求的数据
/**
 *  读取客户端的请求的数据
 *
 *  @param sock 客户端
 *  @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];
    NSLog(@"读取数据 sock:  %@  %@",sock,str);
    //获取客户端返回的数据
    NSInteger code = [str integerValue];
    //默认给客户端的数据
    NSString *reponseStr=nil;
    switch (code) {
        case 0:
            reponseStr = @"没有充值服务....\n";
            break;
        case 1:
             reponseStr = @"当前没有员工....\n";
            break;
        case 2:
             reponseStr = @"打折优惠5折....\n";
            break;
        case 3:
             reponseStr = @"特殊服务一个....\n";
            break;
        case 4:
             reponseStr = @"退出成功....\n";
            break;
            
        default:
            break;
    }
   
    //2.处理请求,返回数据给客户端
    [sock writeData:[reponseStr dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0];
    if (code==4) {
        //移除客户端
        [self.NewSockets removeObject:sock];
    }
#warning 每次读完数据后,都要调用一次监听数据的方法
    [sock readDataWithTimeout:-1 tag:0];
}
View Code
  • 实例化一个服务监听对象,开始监听
#import <Foundation/Foundation.h>
#import "ServiceListen.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        NSLog(@"Hello, World!");
        //创建一个服务监听对象
        ServiceListen *listen=[[ServiceListen alloc] init];
        //开始监听
        [listen start];
        //开启主运行循环,让服务不能停
        [[NSRunLoop mainRunLoop]run];
        
    }
    return 0;
}
View Code

 

  • 运行程序 ,打开终端-->链接服务器

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!