Linux: listen() & socket() & bind() & accept() & connect() & recvfrom()&sendto() & recv()&send()详解

以下函数的头文件:

#incldue
#include
#include
#include

1.socket()

功能:创建socket文件描述符
int socket(int domain,int type,int protocol)
参数说明:
 (1)domain(family):表示套接字的通信域,不同的取值决定了socket的地址类型,其一般取值如下:
      AF_INET:IPV4因特网域
      AF_INET6IPV6因特网域
      AF_UNIX:UNIXAF_ROUTE:路由套接字

 (2)type:是socket的类型,常用如下:
     SOCK_STREAM:有序、可靠、双向的面向连接--->字节流套接字,例如TCP
     SOCK_DGRAM:长度固定的、无连接的不可靠的--->数据报套接字,例如UDP
     SOCK_RAW:原始套接字

  (3)protocol:指定协议,取值如下:
     0:表示选择type类型对应的默认协议
     IPPROROTO_TCP:TCP传输协议
     IPPROTO_UDP:UDP传输协议
     IPPRPTO_SCTP:SCTP传输协议
     IPPROTO_TIPC:TIPC传输协议
  ps:此选项一般都是设为0,让操作系统根据第二个参数的类型去自动匹配协议

返回值:

成功:返回一个整数,是socket的文件描述符
失败:返回-1

ps:此函数可用于TCP和UDP通信中的服务器与客户端

2.bind()

调用socket函数创建套接字描述符时,该套接字描述符时存储在它的协议蔟空间中的,是没有具体的地址的,要使它一个地址相关联,可以调用bind函数使其与地址相关联


功能:绑定端口号(一般都是服务器进行绑定,例如TCP/UDP的服务器)

int bind(int socket,const struct sokcaddr* address,
         socklet_t address_len)
参数说明:
 (1socket:套接字描述符,是函数socket的返回值
 (2)address:sockadrr是本地的地址(服务器的地址),是一个sockaddr结构指针,该结构中包含了要进行结合的IPD地址和端口号
 (3)address_len:是address缓冲区的长度

返回值

成功:返回0
失败:返回-1

ps:此函数可用于TCP和UDP通信中的服务器与客户端

3.listen()

在进行TCP通信时,在进行通信之前,需要先建立连接,listen函数把TCP的socket变为被动的模式,此时才能允许客户端来建立连接

功能 :开始监听(服务器不知道需要与谁进行连接,因此,她不会主动的要求与某个进程连接,只是一直监听是否有其他的用户进程与之连接,然后响应该连接请求,并对他做出处理(一个服务器可同时处理多个客户机的请求连接) )

int listen(int socket,int backlog)
参数说明:
 (1)socket:是socket函数的返回值(此参数用于标识一个已经捆绑但是未连接的套接字描述符
 (2)backlog:同一时刻,操作系统允许的最大的可进行连接的客户端数(提示内核监听队列的最大长度),此参数一般是510,一般选择5
ps:监听队列的长度如果超过backlog,服务器将不再受理新的客户连接,客户端也将收到ECONNREFUSED错误信息,而且一般可以连接的客户端数为backlog+1.

返回值

成功:返回0
失败:返回-1

ps:此函数用于TCP通信中的服务器端

4.accept()

功能:接收一个客户端连接
int accept(int socket,struct sockaddr* address,
           socklen_t address*address_len)
参数说明:
       (1)socket:是函数socket的返回值
       (2)address:是对端(客户端)的地址
       (3)address_len:该socket地址(对端地址)的长度

返回值

成功:返回一个新的套接字描述符,该套接字描述符唯一的标识了被接受的这个连接,服务器通过读写此描述符来与客户端进行通信
失败:返回-1

TCP中:accept函数的返回值与socket函数返回值的区别:

(1)socket函数返回的套接字描述符是用于bind和listen的,可以与所有的客户端
进行通信
(2)accept函数返回的套接字描述符是唯一的标识某一个客户端的,与此客户端进行通信只能用此函数返回的描述符

例如:
假如套接字描述符是电话号码,那socket函数的返回值是你的电话号码,你有很多朋友,他们各自都有自己的电话号码,他们要与你进行打电话的话,他们会打你电话,而你要与他们进行联系的话,需要打他们的电话号码。对你来说,每一个人都有自己的电话号码,而对他们来说,他们所有人用于联系你的电话号码都是一样的,此处你的电话号码就是socket函数的返回值,而你所有朋友的号码就是accept函数的返回值,每一个人的accept的返回值都不一样

注意

此函数一般是与listen匹配使用,listen是让服务器处于一种监听状态,好让服务器可以接收客户端发起的请求,而accept是用于接收某一个客户端的连接。

ps:此函数用于TCP通信中的服务器端

5.connect()

在处理面向连接的网络服务时,例如TCP,进行通信交换数据之前必须在请求的进程的套接字和提供服务的进程套接字之间建立连接,例如TCP客户端可调用connect函数来建立与TCP服务器端的一个连接

功能:客户端使用该函数主动与服务器建立连接
int accept(int socket,const struct sockaddr*serv_addr,
           socklen_t adrdrlen)
参数说明:
       (1)socket:是socket函数的返回值
       (2)serv_addr:是服务器的socket地址
       (3)addrlen:是服务器的socket地址的长度

返回值

1.成功:返回0
一旦成功建立连接,socket就唯一标识了这个连接,客户端就可以读写socket来与服务器进行通信了
2.失败:返回-1

ps:此函数用于TCP通信中的客户机端

6.recvfrom()

功能:在进行UDP通信时,用于接收收据
int recvfrom(int socket,void*buf,size_t len,int flags,
             struct sockaddr*src_addr,socklen_t* addrlen);
参数说明:
     (1)socket:是socket函数的返回值,用于标识一个已连接的套接字描述符
     (2)buf:接收数据的缓冲区
     (3)len:接收数据换缓冲区的长度
     (4)flags:一般设为0
     (5)src_addr:指向对端的地址
     (6)addrlen:对端地址的长度

返回值

成功:返回接收到的字节数
失败:返回SOCKET_ERROR

ps:此函数用于UDP通信的客户端和服务器

7.sendto()

功能:用于发送数据
int sendto(int socket,const void*buf,size_t len,int flags,
           const struct sockaddr*dest_addr,socklen_t addrlen);
参数说明:
      (1)socket:是函数socket的返回值
      (2)buf:待发送数据的缓冲区
      (3)len:是buf的长度
      (4)flags:此参数一般设为0
      (5)dest_addr:是对端的地址
      (6)addrlen:是对端地址的长度

返回值

成功:返回一个整数,此数是发送的字节数
失败:返回SOCKET_ERROR

ps:此函数一般用于UDP通信的客户端与服务器

因为UDP进行通信时,没有连接,所以每次在进行发送数据时,都需要指定地址,而接收数据也需要知道是谁发的

sendto函数和recvfrom函数也可以用于面向连接(TCP)的socket的数据读写,只需要把这两个函数最后的两个参数都设置为NULL就好,以忽略发送端和接收端的socket地址(因为TCP在通信时,首先是与对方建立连接的,然后在发送数据的,所以已经知道对方的数据了,不需要指定地址了)

8.recv()

功能:用于对TCP的数据进行写
原型:ssize_t recv(int socket,void*buf,size_t len,int flags)
  参数说明:
    (1socket:是函数socket的返回值
    (2)buf:指定读缓冲区的位置
    (3)len:指定读缓冲区的大小
    (4)flags
     ps:flag通常设为0
        MSG_DONTWAIT:表明对socket的此次操作将是非阻塞的
        MSG_WAITALL:该操作仅在读取到指定数量的字节后才返回
        MSG_PEEK:只是窥探读缓冲区中的数据,此次读操作不会导致这些数据
                  被清除,只是查看了一下,数据还存在于缓冲区中的
ps: recv用于在缓冲区中读取数据,数据在缓冲区被读之后,一般是被删除,但
    是如果recv加了参数MSG_PEEK,那就会使数据在被读了之后,还是在缓冲
    区中的,并不会被删除
        MSG_OOB:发送或接收紧急数据

返回值

成功

返回一个整数,此整数表示的是读取的字节数(也就是返回实际读到的数据的长度),此数可能小于我们期望的长度,因此可能需要多次调用recv,才能读到完整的数据,recv也可能返回0,这表示通信双方已经关闭连接了

失败

返回-1,并设置errno

9.send

功能:用于对TCP的数据进行读
原型:ssize_t send(int socket,const void*buf,size_t len,int flags)
  参数说明
       (1socket:是函数socket的返回值
       (2)buf:标记的是写缓冲区的位置
       (3)len:标记的是写缓冲区的大小
       (4)flags
        ps:flags一般设为0
           MSG_CONFIRM:指示数据链路层协议持续监听对方的回应,直到得到
                        答复,它仅能用于SOCK_DGRAM(TCP)和SOCK_RAW类
                        型的socket
           MSG_DONTROUTE:表示不查看路由表,直接将数据发送给本地局域
                         网络内的主机,这表示发送者确切地知道目标主机
                         就在本地网络上
           MSG_DONTWAIT:对socket的此次操作是非阻塞的
           MSG_MORE:告诉内核应用程序还有更多数据要发送,内核将超时等待
                    新数据写入TCP发送缓冲区后一并发送,这样可防止TCP
                    发送过多小的报文段,从而提高传输效率
           MSG_OOB:发送或者接收紧急数据
           MSG_NOSIGNAL:往读端关闭的管道或者socket连接中写数据时
                         不引发SIGPIPE信号

返回值

成功

返回一个整数,此整数表示的是发送的字节数(也就是往socket中写入数据的长度)

失败

返回-1,并设置errno

注:对于文件的读写操作read和write同样适用于socket,但是socket编程接口提供了几个专门用于socket数据读写的系统调用,他们增加了对数据读写的控制,其中用于TCP流数据读写的系统调用是recv和send
Linux: listen() & socket() & bind() & accept() & connect() & recvfrom()&sendto() & recv()&send()详解_第1张图片

你可能感兴趣的:(linux)