socket API(linux)

6 篇文章 0 订阅
4 篇文章 0 订阅

1.socket函数

 (1)定义

   作用:创建socket

 #include <sys/types.h>          /* See NOTES */
 #include <sys/socket.h>

 int socket(int domain, int type, int protocol);

(2)参数

  • domain

    设置网络通信域,即通信的协议设置:

名称含义
 AF_UNIX, AF_LOCAL本地通信
AF_INETIPv4 Internet协议
AF_INET6IPv6 Internet协议
AF_IPXIPX-Novell协议
AF_NETLINK内核用户界面设备
AF_X25ITU-T X25 / ISO-8208协议
AF_AX25Amateur radio AX.25
AF_ATMPVC原始ATM PVC访问
AF_APPLETALKAppletalk
AF_PACKET底层包访问
AF_ALG内核加密API
  • type

     参数type用于设置套接字通信的类型:

名称含义
SOCK_STREAMTCP连接(提供序列化的、可靠的、双向连接的字节流,支持带外数据传输)
SOCK_DGRAMUDP连接(无连接状态、不可靠的报文)
SOCK_SEQPACKET序列化包,提供一个序列化的、可靠的、双向的基本连接的数据传输通道,数据长度定常。每次调用读系统调用时数据需要将全部数据读出
SOCK_RAWRAW类型,提供原始网络协议访问
SOCK_RDM提供可靠的数据报文,不过可能数据会有乱序
  • protocol

    用于制定某个协议的特定类型.

  例如创建一个流式的socket:

int fd = socket(AF_INET, SOCK_STREAM, 0);

(3)返回值

    返回值中fd>0代表创建成功,此时fd的值就是创建文件描述符的值;fd = -1表示创建失败,可以通过errno来查看具体失败原因。

errno值含义
EACCES没有权限建立制定的domain的type的socket

EAFNOSUPPORT

不支持所给的地址类型
EINVAL不支持此协议或者协议不可用
EMFILE进程文件表溢出

ENOBUFS or ENOMEM

内存不足,socket只有到资源足够或者有进程释放内存

EPROTONOSUPPORT

制定的协议type在domain中不存在

2.bind函数

(1)定义

作用:套接字与一个地址相关联,即地址绑定。

 #include <sys/types.h>          /* See NOTES */
 #include <sys/socket.h>

 int bind(int sockfd, const struct sockaddr *addr,
                socklen_t addrlen);

(2)参数

  • sockfd

    上一步socket创建的返回值fd(前提创建成功了)

  • sockaddr

       sockaddr结构体定义如下:

struct sockaddr {
               sa_family_t sa_family;
               char        sa_data[14];
           }

 这个数据结构逐渐被舍弃(参考:https://blog.csdn.net/ZWE7616175/article/details/80252048

代替的是:struct sockaddr_in,在使用的时候需要把第二个结构强转成sockaddr

struct sockaddr_in
  {
    __SOCKADDR_COMMON (sin_);
    in_port_t sin_port;                 /* Port number.  */
    struct in_addr sin_addr;            /* Internet address.  */

    /* Pad to size of `struct sockaddr'.  */
    unsigned char sin_zero[sizeof (struct sockaddr) -
                           __SOCKADDR_COMMON_SIZE -
                           sizeof (in_port_t) -
                           sizeof (struct in_addr)];
  };

上面的不太直观,翻译一下:

struct sockaddr_in { 
   uint8_t sa_len;   /* 结构体长度*/ 
     short int sin_family; /* 通信类型 */ 
   unsigned short int sin_port; /* 端口 */ 
   struct in_addr sin_addr; /* Internet 地址 */ 
   unsigned char sin_zero[8]; /* 未使用的*/ 
   };

struct in_addr {   //sin_addr的结构体类型in_addr 原型
   unsigned long s_addr;     /*存4字节的 IP 地址(使用网络字节顺序)。*/
   };
  • sddrlen

    addr结构的长度。

(3)返回值

    返回值为0时表示绑定成功,-1表示绑定失败,errno的错误值:

errno值含义
EACCES地址被保护,用户的权限不足
EADDRINUSE给定地址已经使用
EBADFsockfd不合法
EINVALsockfd已经绑定到其他地址

ENOTSOCK

描述符不是socket描述符

EADDRNOTAVAIL

接口不存在或者绑定地址不是本地
EFAULTaddr指针超出用户空间
ELOOP解析addr时符号链接过多

ENAMETOOLONG

addr过长
ENOENT文件不存在
ENOMEM内核内存不够

ENOTDIR

不是目录
EROFS只读

 例如:

    struct sockaddr_in bindaddr;
    bindaddr.sin_family = AF_INET;
    bindaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    bindaddr.sin_port = htons(8080);
    if (bind(fd, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) == -1)
    {
        pinttf("bind failed!\n"); 
        return -1;
    }

3.listen

(1)定义:listen()函数将sockfd标记为被动打开的套接字(即变为监听状态),并作为accept的参数用来接收到达的连接请求。

 #include <sys/types.h>          /* See NOTES */
 #include <sys/socket.h>

 int listen(int sockfd, int backlog);

(2)参数:

  • sockfd

    socket类型的文件描述符。

  • backlog

    用来描述sockfd的等待连接队列能够达到的最大值。

(3)返回值

    返回值为0时表示成功,-1表示失败,errno的错误值:

errno值含义

EADDRINUSE

另一个套接字已经绑定在相同的端口上
EBADFsockfd不是有效的文件描述符
ENOTSOCKsockfd不是套接字

EOPNOTSUPP

sockfd不是支持listen操作的套接字类型

4.connect

(1)定义

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>

int connect(int sockfd, const struct sockaddr *addr,
                   socklen_t addrlen);

(2)参数

  • sockfd

    套接字文件描述符

  • sockaddr

    参照struct sockaddr_in(目的地址的IP和端口信息)

  • addrlen

    填sizeof(struct sockaddr_in)

(3)返回值

    返回值为0时表示成功,-1表示失败,errno的错误值:

errno值含义
EACCES没有权限建立制定的domain的type的socket
EBADF无效的socket文件描述符
EISCONN已经连接过了
ETIMEDOUT超时

5.accept

(1)定义:

   尝试接收一个连接

 #include <sys/types.h>          /* See NOTES */
 #include <sys/socket.h>

 int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

 #define _GNU_SOURCE             /* See feature_test_macros(7) */
 #include <sys/socket.h>

 int accept4(int sockfd, struct sockaddr *addr,
                   socklen_t *addrlen, int flags);

(2)参数

  •   sockfd

    socket类型的文件描述符

  • sockaddr

    参照struct sockaddr_in

(3)返回值

   成功时,返回非负整数,该整数是接收到套接字的描述符;出错时,返回-1,相应地设定全局变量errno:

errno值含义
EFAULT 
ENOTSOCK 
EOPNOTSUPP 
EPERM防火墙拒绝此连线
ENOBUFS系统的缓冲内存不足

 

6.send

(1)定义

 #include <sys/types.h>
 #include <sys/socket.h>

 ssize_t send(int sockfd, const void *buf, size_t len, int flags);

(2)参数

  • sockfd

   如果是服务端这个sockfd是accept函数返回的fd

  • buf

    待发送的缓存

  • len

    send指要发送的长度

  • flags

(3)返回值

    返回值>0表示发送的字节数,=0表示对端断开连接,返回-1时:在阻塞模式下为错误,而在非阻塞模式下不一定是错误的,所以要结合errno值来判断。

errno值含义

EAGAIN or EWOULDBLOCK

套接字已标记为非阻塞,而接收操作被阻塞或者接收超时
EINTR操作被信号中断

7.recv

(1)定义

 #include <sys/types.h>
 #include <sys/socket.h>

 ssize_t recv(int sockfd, void *buf, size_t len, int flags);

(2)参数

  • sockfd

    如果是服务端这个sockfd是accept函数返回的fd

  • buf

    待接收的缓存

  • len

    recv指期望接收的长度

  • flags
flags值含义
MSG_DONTWAIT仅本操作非阻塞
MSG_OOB  发送或接收带外数据
MSG_PEEK  窥看外来消息
MSG_WAITALL 等待所有数据

(3)返回值

     返回值>0表示发送的字节数,=0表示对端断开连接,返回-1时:在阻塞模式下为错误,而在非阻塞模式下不一定是错误的,所以要结合errno值来判断。

errno值含义

EAGAIN or EWOULDBLOCK

套接字已标记为非阻塞,而接收操作被阻塞或者接收超时
EINTR操作被信号中断
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值