Socket

作者: DoBetter1 | 来源:发表于2020-02-07 22:39 被阅读0次

1. Socket是啥?

  Socket就是为⽹网络服务提供的⼀一种机制 通信的两端都是 Socket ⽹网络通信其实就是 Socket 间的通信 数据在两个 Socket 间通过 IO 传输 Socket 是纯C语⾔言的,是跨平台的。

2. 创建Socket

int socketId = socket(AF_INET, SOCK_STREAM, 0);
  • domain:协议域,又称协议族(family)。常用的协议族有AF_INET(ipv4)AF_INET6(ipv6)、AF_LOCAL(或称AF_UNIX,Unix域Socket)、AF_ROUTE等。协议族决定了socket的地址类型,在通信中必须采用对应的地址,如AF_INET决定了要用ipv4地址(32位的)与端口号(16位的)的组合、AF_UNIX决定了要用一个绝对路径名作为地址。
  • type:指定Socket类型。常用的socket类型有SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等。流式Socket(SOCK_STREAM)是一种面向连接的Socket,针对于面向连接的TCP服务应用。数据报式Socket(SOCK_DGRAM)是一种无连接的Socket,对应于无连接的UDP服务应用。
  • protocol:指定协议。常用协议有IPPROTO_TCPIPPROTO_UDP、IPPROTO_STCP、IPPROTO_TIPC等,分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议。
  • 返回值:如果调用成功就返回新创建的套接字的描述符,如果失败就返回INVALID_SOCKET(Linux下失败返回-1)。
  • 注意:typeprotocol不可以随意组合,如SOCK_STREAM不可以跟IPPROTO_UDP组合。当第三个参数为0时,会自动选择第二个参数类型对应的默认协议。

3. 建立连接

在建立连接之前需要配置socketAddr

struct sockaddr_in socketAddr;

socketAddr.sin_family   = AF_INET; //ipv4
socketAddr.sin_port     = SocketPort; //端口

//初始化一个ip
struct in_addr  socketIn_addr;
socketIn_addr.s_addr    = SocketIP; //ip

//把ip赋值socketAddr
socketAddr.sin_addr     = socketIn_addr;  

//其中有两个宏定义:
//htons : 将一个无符号短整型的主机数值转换为网络字节顺序,不同cpu 是不同的顺序 (big-endian大尾顺序 , little-endian小尾顺序)
#define SocketPort htons(8040)
//inet_addr是一个计算机函数,功能是将一个点分十进制的IP转换成一个长整数型数
#define SocketIP   inet_addr("127.0.0.1")
  • __uint8_t sin_len; 假如没有这个成员,其所占的一个字节被并入到sin_family成员中
  • sa_family_t sin_family; 一般来说AF_INET(地址族)PF_INET(协议族)
  • in_port_t sin_port; // 端口
  • struct in_addr sin_addr; // ip
  • char sin_zero[8] 没有实际意义,只是为了 跟SOCKADDR结构在内存中对齐

把配置好的socketAddr传入connect方法:

int result = connect(socketId, (const struct sockaddr *)&socketAddr, sizeof(socketAddr)); 

connect方法的参数:

  • 参数一:套接字描述符。
  • 参数二:指向数据结构sockaddr的指针,其中包括目的端口IP地址
  • 参数三:参数二sockaddr的长度,可以通过sizeof(struct sockaddr)获得。
  • 返回值:成功则返回0,失败返回非0,错误码GetLastError()

4. 发送消息

const char *msg = @"消息".UTF8String;
//send(`int`, `const void `, `size_t`, `int`)
ssize_t sendLen = send(socketId, msg, strlen(msg), 0);

参数:

  • s:一个用于标识已连接套接口的描述字。
  • buf:包含待发送数据的缓冲区。
  • len:缓冲区中数据的长度。
  • flags:调用执行方式。
  • 返回值:如果成功,则返回发送的字节数,失败则返回SOCKET_ERRO,一个中文对应 3 个字节!UTF8 编码!

5. 接收消息

uint8_t buffer[1024];
ssize_t recvLen = recv(socketId, buffer, sizeof(buffer), 0);

参数:

  • 客户端socket

  • 接收内容缓冲区地址

  • 接收内容缓存区长度

  • 接收方式,0表示阻塞,必须等待服务器返回数据

  • 返回值: 如果成功,则返回读入的字节数,失败则返回SOCKET_ERROR

终端监控端口命令:

nc -lk 8040
image.png

相关文章

网友评论

      本文标题:Socket

      本文链接:https://www.haomeiwen.com/subject/iufbxhtx.html