Linux C 网络_绑定套接字函数

在创立了套接字之后需要将本地地址和套接字绑定在一起,此时可以调用 bind 函数。

#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

参数 sockfd 是使用 socket 函数创建的套接字对应的套接字描述符,addr 是本地地址,addrlen 是套接字对应的地址结构长度;如果 bind 函数执行成功,则返回 0,否则返回 -1。

在网络通信中服务器和客户端都可以使用 bind 函数来设置套接字地址,通常来说有以下5种模式:

  • 服务器指定套接字地址的公认端口号,不指定IP地址,服务器调用函数bind时,如果设置套接字的IP地址为特殊的INADDR ANY, 表示它愿意接收来自任何网络设备接口的客户端连接,这是服务器最经常使用的绑定方式。
  • 服务器指定套接字地址的公认端口号和IP地址,服务器调用函数bind时,如果设置套接字的 IP 地址为某个本地 IP 地址,则表示服务器只接收来自对应于这个 IP 地址的特定网络设备接口的客户端连接。如果这台机器只有一个网络设备接口,则这和第一种情况是没有区别的,但当这台机器有多个网络设备接口时,我们可以用这种方式来限制服务器的接收范围。
  • 客户端指定套接字地址的连接端口号,在一般情况下,客户端不用指定自己的套接字地址的端口号,当客户端调用函数 connect 进行 TCP 连接时,系统会自动为它选择一个未用的端口号,并且用本地的 IP 地址来填充套接字地址中的相应项,但在有的情况下,客户端需要使用特定端口号。
  • 指定客户端的 IP 地址和连接端口号,表示客户端使用指定的网络设备接口和端口号进行通信。
  • 指定客户端的 IP 地址,表示客户端使用指定的网络设备接口进行通信,系统自动为客户端选择一个未用的端口号。一般情况下,只有在主机有多个网络设备接口时使用。
C/S IP port 说明
服务器 INADDR_ANY 非 0 值 指定服务器的公认端口号
服务器 本地 IP 地址 非 0 值 指定服务器的 IP 地址和公认端口号
客户端 INADDR_ANY 非 0 值 指定客户端的连接端口号
客户端 本地 IP 地址 非 0 值 指定客户端的 IP 地址和连接端口号
客户端 本地 IP 地址 0 指定客户端的 IP 地址

在编写客户端程序时,通常不要使用固定的客户端端口号,除非是在必须使用特定端口的情况下,因为固定客户机端口号会带来一些不便, 例如:

  • 服务器执行主动关闭操作:服务器最后进入 TIME_WAIT 状态。当客户机再次与这个服务器进行连接时,仍使用相同的客户机端口号,于是这个连接与前次连接的套接字对完全相同,但是因为前次连接处于 TIME_WAIT 状态,并未消失,所以这次连接请求被拒绝,函数 connect 以错误返回。
  • 客户端执行手动关闭操作:客户端最后进入 TIME_WAIT 状态,当立刻再次执行这个客户机程序时,客户机将继续与这个固定客户机端口号绑定,但因为前次连接处于 TIME_WAIT 状态,并未消失,系统会发现这个端口号仍被占用,所以这次绑定操作失败,函数 bind 以错误返回。

【例2】使用 bind 函数绑定套接字
应用代码定义了一个 IPv4 的套接字地址数据结构变量 addr,首先使用 socket 函数创建一个套接字,然后使用 bzero 函数将结构变量 addr 的值清空,分别设置结构体的各个分量,最后调用函数将这个变量绑定到刚刚创建的套接字上。

实例的应用代码如下:

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#define PORT 5555    //定义端口号
int main(int argc, char *argv[])
{
    int sockfd;     //定义套接口描述符
    struct sockaddr_in addr;   //定义 IPv4 套接口地址数据结构 addr 
    int addr_len = sizeof(struct sockaddr_in);   
    if(sockfd = socket(AF_INET, SOCK_STREAM,0))<0)   //建议一个 socket
    {
        printf("创建套接字失败!\n");
        return 1;
    }
    bzero(&addr, sizeof(struct sockaddr_in));  //清空表示地址的结构体变量
    addr.sin_family = AF_INET;    //设置 addr 的成员信息
    addr.sin_port = htons(PORT);
    addr.sin_addr.s_addr = htonl(INADDR_ANY);  //IP地址设为本机IP
    if(bind(sockfd, (struct sockaddr *)(&addr), sizeof(strut sockaddrr))<0)
    {
        printf("绑定端口失败!");
        return 1;
    }
    return 0;
}

该程序没有输出。

发布了70 篇原创文章 · 获赞 131 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_43239560/article/details/103129724