Socket

作者: 李伟13 | 来源:发表于2020-10-14 21:39 被阅读0次

Socket

socket可以算是一种特殊的文件,是"Open--Write/Read--Close"模式的一种实现,可读、可写、可控制、可关闭。普通文件的打开操作返回一个文件描述符,socket返回一个socket描述符

socket的创建

#include <sys/socket.h>

int socket(int family, int type, int protocol);
httpfd = socket(AF_INET, SOCK_STREAM, 0);

sucess return socketfd;
failed return -1; and set errno(在err流里?)
  • family(domain 协议域)AF_INET --- IPV4(ipv6为AF_INET6)
  • type(socker类型)SOCK_STREAM --- 面向连接的稳定数据传输
  • protocol(协议)0选择与type一致的协议

  • 其中理论上建立socket时是指定协议,应该用PF_xxxx,设置地址时应该用AF_xxxx,但是其实他们值是一致的,所以有很多混用的情况
  • 建议:对于socketpair与socket的domain参数,使用PF_LOCAL系列,而在初始化套接口地址结构时,则使用AF_LOCAL。

例如:

    z = socket(PF_LOCAL, SOCK_STREAM, 0);
    addr.sin_family = AF_INET;

socket的命名

创建socket只是指定了地址族,并没有具体地址.(就只有socket文件描述符,并没有绑定socket地址?).

  • 将一个socket与socket地址的绑定称为命名.
  • 在服务器程序中,只有命名后客户端才知道该如何连接它.(客户端就不需要命名,使用操作系统自动分配的socket地址)
#include <sys/types.h>
#include <sys/sockets.h>
int bind(int socketfd, const struct sockaddr* my_addr, socklen_t addrlen);
success return 0
failed return -1 and set errno

struct sockaddr_in为ipv4的地址协议族



其中,port和sin_addr为网络字节序,hton(), htonl(),htons();
sock_addr常用于bind connect recvfrom sendto 等函数的参数.
#include <arpe/inet.h>  
int inet_pton(int family, const char *strptr, void *addrptr);     //将点分十进制的ip地址转化为用于网络传输的数值格式  
        返回值:若成功则为1,若输入不是有效的表达式则为0,若出错则为-1  
inet_pton(AF_INET, ip, &address.sin_addr)
const char * inet_ntop(int family, const void *addrptr, char *strptr, size_t len);     //将数值格式转化为点分十进制的ip地址格式  
        返回值:若成功则为指向结构的指针,若出错则为NULL

设置sockaddr的一般步骤

cosnt char* ip;
...
struct sockaddr_in address;
bzero(&address, sizeof(address));    #c
memset(&address, 0, sizeof(address));  #cpp
address.sin_family = AF_INET;
inet_pton(AF_INET, ip, &address.sin_addr);

socket监听

#include <sys/socket.h>
int listen(int sockfd, int backlog);

sucess return 0;
failed return -1 and set errno

backlog参数提示内核监听队列的最大长度,典型值为5,在linux内核版本2.2之后,表示完全连接状态的socket上限(ESTABLISHED)
到这一步已经可以建立连接了,只不过还不能进行通信

接受连接accept

#Include <sys/types.h>
#include <sys/socket.h>
int accept(int listenfd, struct sockaddr *addr, socklen_t *addrlen);

sucess return 0;
failed return -1 and set errno

如果监听队列中处理ESTABLISHED状态的client出现异常,对accept没有影响,accept只是从监听队列中取出链接.
V:我觉得accept就像是bind的另一种形式.把client客户端的信息映射到connfd上,然后存入文件描述符表中.

发起连接 connect

#Include <sys/types.h>
#include <sys/socket.h>
int connect(int sockfd, cosnt struct sockaddr *serv_addr, socklen_t *addrlen);

sucess return 0;
failed return -1 and set errno

关闭连接 close

#include <unistd.h>
int close(int fd);

close系统调用并非总是立即关闭一个链接,而是将fd的引用计数减1

相关文章

网友评论

      本文标题:Socket

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