Socket

Socket的基本概念

1.定义

网络上两个程序通过一个双向通信连接实现数据交互,这种双向通信的连接叫做Socket(套接字)。

2.本质

网络模型中应用层与TCP/IP协议族通信的中间软件抽象层,是它的一组编程接口(API),也即对TCP/IP的封装。TCP/IP也要提供可供程序员做网络开发所用的接口,即Socket编程接口。

Socket的位置

3.要素

Socket是网络通信的基石,是支持TCP/IP协议的网络通信的基本操作单元,包含进行网络通信的必须的五种信息:

连接使用的协议

本地主机的IP地址

本地进程的协议端口

远程主机的IP地址

远程进程的协议端口

4.特性

Socket可以支持不同的传输协议(TCP或UDP),当使用TCP协议进行连接时,该Socket连接就是一个TCP连接;同理,当使用UDP协议进行连接时,该Socket连接就是一个UDP连接。

多个TCP连接或多个应用程序进程可能需要通过同一个TCP协议端口传输数据。为了区别不同的应用程序进程和连接,计算机操作系统为应用程序与TCP/IP协议交互提供了套接字(Socket)接口。应用层可以和传输层通过Socket接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。

5.连接

建立Socket连接至少需要一对套接字,分别运行于服务端(ServerSocket)和客户端(ClientSocket)。套接字直接的连接过程氛围三个步骤:

Step1服务器监听

服务端Socket始终处于等待连接状态,实时监听是否有客户端请求连接。

Step2客户端请求

客户端Socket提出连接请求,指定服务端Socket的地址和端口号,这时就可以向对应的服务端提出Socket连接请求。

Step3连接确认

当服务端Socket监听到客户端Socket提出的连接请求时作出响应,建立一个新的进程,把服务端Socket的描述发送给客户端,该描述得到客户端确认后就可建立起Socket连接。而服务端Socket则继续处于监听状态,继续接收其他客户端Socket的请求。

iOS客户端Socket的实现

1. 数据流方式

    - (IBAction)connectToServer:(id)sender {

        // 1.与服务器通过三次握手建立连接

        NSString *host = @"192.168.1.58";

        int port =1212;


        //创建一个socket对象

        _socket = [[GCDAsyncSocket alloc] initWithDelegate:self

            delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)];


        NSError *error =nil;


        // 开始连接

        [_socket connectToHost:host

            onPort:port

            error:&error];


        if(error) {

            NSLog(@"%@",error);

        }

}

#pragma mark - Socket代理方法

// 连接成功

- (void)socket:(GCDAsyncSocket *)sock

didConnectToHost:(NSString *)host

port:(uint16_t)port {

    NSLog(@"%s",__func__);

    }



    // 断开连接

    - (void)socketDidDisconnect:(GCDAsyncSocket *)sock

withError:(NSError *)err {

    if(err) {

        NSLog(@"连接失败");

    }else{

        NSLog(@"正常断开");

    }

    }



    // 发送数据

    - (void)socket:(GCDAsyncSocket *)sock

didWriteDataWithTag:(long)tag {


    NSLog(@"%s",__func__);


    //发送完数据手动读取,-1不设置超时

    [sock readDataWithTimeout:-1

        tag:tag];

}

// 读取数据

-(void)socket:(GCDAsyncSocket *)sock

didReadData:(NSData *)data

withTag:(long)tag {


    NSString *receiverStr = [[NSString alloc] initWithData:data

        encoding:NSUTF8StringEncoding];


    NSLog(@"%s %@",__func__,receiverStr);

}

2.基于第三方开源库CocoaAsyncSocket

2.1客户端通过地址和端口号与服务端建立Socket连接,并写入相关数据。

    - (void)connectToServerWithCommand:(NSString *)command

{

    _socket = [[GCDAsyncSocket alloc] initWithDelegate:selfdelegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)];

    [_socket setUserData:command];


    NSError *error =nil;

    [_socket connectToHost:WIFI_DIRECT_HOST onPort:WIFI_DIRECT_PORT error:&error];

    if(error) {

        NSLog(@"__connect error:%@",error.userInfo);

    }


    [_socket writeData:[command dataUsingEncoding:NSUTF8StringEncoding] withTimeout:10.0f tag:6];

}

2.2实现CocoaAsyncSocket的代理方法

#pragma mark - Socket Delegate

- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port

{

    NSLog(@"Socket连接成功:%s",__func__);

}

-(void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err{

    if(err) {

        NSLog(@"连接失败");

    }else{

        NSLog(@"正常断开");

    }


    if([sock.userData isEqualToString:[NSString stringWithFormat:@"%d",SOCKET_CONNECT_SERVER]])

    {

        //服务器掉线 重新连接

        [selfconnectToServerWithCommand:@"battery"];

    }else

    {

        return;

    }

}

-(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag {

    NSLog(@"数据发送成功:%s",__func__);

    //发送完数据手动读取,-1不设置超时

    [sock readDataWithTimeout:-1tag:tag];

}

-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {

    NSString *receiverStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

    NSLog(@"读取数据:%s %@",__func__,receiverStr);

}

你可能感兴趣的:(Socket)