TCP套接字函数

1. socket函数

#include <sys/socket.h>
int socket(int family, int type, int protocol);
//若成功则返回非负描述符
//若出错返回-1

2.connect函数

#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr* servaddr, socklen_t addrlen);
//若成功则返回0,出错返回-1
  • 第二个参数是一个指向套接字地址结构的指针。

  • 客户再调用函数connect前不必非得调用bind函数。

  • 调用connect函数将激发TCP的三路握手,而且仅在连接建立成功或出错时才返回。

    出错情况:
    (1)TCP客户端没有收到SYN分节的响应,返回ETIMEDOUT
    (2)若对SYN的响应为RST,表明服务器在指定端口没有进程在等待连接。
    (3)SYN在中间某个路由器引发“目的地不可达”的ICMP错误。
    
  • 若connect失败则该套接字不再可用,必须关闭。

3.bind函数

#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *myaddr, aocklen_t addrlen);
//若成功则为0,出错返回-1
  • 若指定端口号0,内核就会在bind被调用时选择一个临时端口。
  • 若指定IP地址为通配地址,则内核将等到套接字已连接(TCP)时才选择一个IP地址。
  • 对于IPv4,通配地址由常值INADDR_ANY指定,其值一般为0。
struct sockaddr_in servaddr;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  • 若让内核为套接字选择一个临时端口号,bind并不返回所选择的值。为了得到内核所选择的临时端口值,必须调用getsockname()函数。

4.listen函数

#include <sys/socket.h>
int listen(int sockfd, int backlog);
//若成功则为0,出错返回-1
  • 第二个参数规定了内核应该为相应套接字排队的最大连接个数。

    内核为任何一个给定的监听套接字维护两个队列
    (1)未完成连接队列,已由客户发出SYN并到达服务器,而服务器正等待完成相应的三路握手。
    (2)已完成连接队列,每个已完成三路握手对应其中一项。
    (3)两队列之和不超过backlog。
    

在这里插入图片描述

  • 当进程调用accept时,已完成连接队列中的对头项将返回给进程。
  • 指定一个比内核能够支持的值还要大的backlog也是可以接受的,内核会做相应的截短。
  • 当一个客户SYN到达时,若队列是满的,TCP就忽略该分节,不发送RST。

5.accept函数

#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);
  • 函数的第一个套接字为监听套接字,其返回值为已连接套接字。

6.close函数

#include <sys/socket.h>
int close(int sockfd);
//成功则返回0,出错返回-1
  • 调用该函数会发生FIN分节,随后是正常的TCP连接终止序列。

  • TCP将尝试发送已排队等待发送到对端的任何数据,发送完毕后是正常的TCP连接终止序列。

    父进程关闭已连接套接字只是导致相应描述符的引用计数值减1,若我们确实想在某个TCP连接上发送一个FIN,可以调用shutdown函数。
    

7.getsockname()和getpeername()

#include <sys/socket.h>
int getsockname(int sockfd, struct sockaddr *localaddr, socklen_t *addrlen);
int getpeername(int sockfd, struct sockaddr *peeraddr, socklen_t *addrlen);
  • 在一个没有调用bind的TCP客户,connect成功返回后,getsockname用于返回由内核赋予该连接的本地IP地址和本地端口号。

  • 在以端口号0调用bind后,getsockname返回由内核赋予的本地端口号。

  • 在一个以通配IP地址调用bind的服务器,与某个客户的连接一旦建立(accept返回),getsockname就可以用于返回内核赋予该连接的本地IP地址。

发布了2 篇原创文章 · 获赞 0 · 访问量 18

猜你喜欢

转载自blog.csdn.net/m0_46390964/article/details/104510246