Socket详解《一》

2019-02-28  本文已影响0人  冰棍儿好烫嘴

本文使用最基础的socket API实现客户端和服务端的通信。

socket 是c语言的API,使用过程中使用到大量的c语言语法,在过程中会一一描述

需要倒入的头文件:

#import  <sys/socket.h>

#import <netinet/in.h>

#import <arpa/inet.h>

socket通信一般分为四个步骤:

1、创建socket并连接服务器

   //1创建socket
    //第一个参数:domain 协议簇 制定IPv4或者IPv6
    //第二个参数:Type socket类型 流socket 数据报socket
    //第三个参数:协议类型 TCP/UDP
    int clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

自己调试的时候,可以使用终端创建本地服务,本机IP是127.0.0.1 ,端口号可以自己创建,使用nc -lk 端口号来创建端口。本文中对应的端口号为12345.

  //连接服务器
   //创建一个sockaddr_in类型(为结构体)的地址,包含domain 协议簇 IP 端口号 字节顺序 等信息
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    //调整字节顺序,从大到小或者从小到大。要和后台和其他端一致
    addr.sin_port = htons(12345);
    //连接
    //第一个参数:socket的描述符
    //第二个参数:结构体 sockaddr_in类型的地址
    //第三个参数:结构体长度 sizeof()
    int result = connect(clientSocket, (const struct sockaddr *) &addr, sizeof(addr));

connect函数会返回一个int类型的值。0为连接成功,!=为对应的错误码,可以在百度词条搜索connect查看错误码对应的问题

2、发送数据

  //发送数据
    /**
     参数:
     带一个参数:socket
     第二个参数:要发送的数据的指针
     第三个:数据的大小,字符数
     第四个:是否要阻塞线程,一般填0
     */
    
    const char * str = sendMsg.UTF8String;
    ssize_t sendCount = send(self.clientSocket, str, strlen(str), 0);
     //返回值:成功则返回实际传送出去的字符数,失败返回-1,错误原因存于errno 中
    NSLog(@"发送的字节数 %zd",sendCount);

3、接收服务器数据

  //接受服务器返回的数据
    /**
     带一个参数:socket
     第二个参数:接受的字节数组
     第三个:数据的大小,字符数
     第四个:是否要阻塞线程,一般填0
     */
    
    uint8_t buffer[1024];
    ssize_t recvCont = recv(self.clientSocket, buffer, sizeof(buffer), 0);
    //把字节数组转换成字符串
    NSData * recvData = [NSData dataWithBytes:buffer length:recvCont];
    NSString * recvMsg = [[NSString alloc]initWithData:recvData encoding:NSUTF8StringEncoding];
    //    NSLog(@"收到的数据:%@",recvMsg);

4、关闭连接

    //关闭连接
    close(self.clientSocket);

通过以上4个步骤就能实现客户端和服务端简单的相互通信。
下面贴上效果图


手机端效果 终端效果
上一篇 下一篇

猜你喜欢

热点阅读