Linux C 网络_建立连接函数

当使用 socket 函数建立一个套接字并且绑定了地址之后,即可使用 connect 函数来和服务器建立一个连接。

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

其中参数 sockfd 是套接字创建函数 socket 返回的套接字描述符,参数 addr 指定远程服务器的套接字地址,包括服务器的 IP 地址和端口号;参数 addrlen 指定这个套接字地址的长度;当调用成功后返回0,否则返回 -1。

在调用 connect 函数建立连接之前,客户端应用代码需要指定服务器端进程的有套接字地址,而
客户端通常不会指定自己的套接字地址,Linux 会自动从1024 ~ 5000 的端口范围之中为客户端分配一个未被使用的端口号,然后将该端口号和本机的 IP 地址结合在一起放入套接字地址中。

当客户端调用函数 connet 来主动建立连接时,这个函数将启动 TCP 协议的 3 次握手过程,在连接建立之后或发生错误时,函数返回。连接过程中可能有如下几种错误情况:

  • 如果客户机 TCP 协议没有接收到对它的 SYN 数据段确认,则函数以错误返回,错误类型为 ETIMEOUT。通常情况下,TCP 协议在发送 SYN 数据段失败之后,会多次发送 SYN 数据段,在所有的发送都宣告失败之后,函数以错误返回。
  • 如果远程 TCP 协议返回一个 RST 数据段,则函数立即以错误返回,错误类型为 ECONNREFUSED。当远程机器在 SYN 数据段指定的目的端口号处没有服务器进程在等待连接时,远程机器的 TCP 协议将发送一个 RST 数据段,向客户机报告这个错误。客户机的 TCP 协议在接收到 RST 数据段之后,不再继续发送 SYN 数据段,函数立即以错误返回。
  • 如果客户机的 SYN 数据段导致某个路由器产生 “目的地不可到达” 类型的 ICMP 消息,则函数以错误返回,错误类型为 EHOSTUNREACH 或 ENETUNREACH。通常情况下,TCP 协议在接收到这个 ICMP 消息之后,记录这个消息,然后继续几次发送 SYN 数据段,在所有的发送都宣告失败之后,TCP 协议检查这个 ICMP 消息,函数以错误返回。

如果调用函数 connect 失败,应该用函数 close 关闭这个套接字描述符,不能再次用这个套接字描述符来调用函数 connect。

【例3】使用 connect 函数建立连接
应用代码使用 PORT 和 REMOTE_IP 来分别定义一个端口号和一个 IP 地址,然后分别调用 socket 和 bind 函数来创建套接字和绑定套接字,最后使用 connect 函数来连接 argv[1] 参数中所指定的 IP 地址。

实例的应用代码如下:

#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fentl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#define PORT 80  //定义一个端口号
#define REMOTE_IP "59.175.132.70"  //定义一个IP地址

int main(int argc, char *argv[])
{
    int sockfd;
    struct sockaddr_in addr;  //定义 IPV4 套接字地址数据结构 addr
    if(argc != 2)
    {
        printf("请输入正确的IP地址字符串。\n");
        return 2;
    }
    if(sockd = socket(A_INET, SOCK_STRAMOY, 0))<0) //建立一个 socket
    {
        printf("创建套接字失败!\n");
        return 1;
    }
    bzero(&addr,sizeof(struct sockaddr_in));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(PORT);
    addr.sin_addr.s_addr = inet_addr(argv[1]);  //从argv[1]中获得目标的IP地址
    if(connect(sockfd, (struct sockaddr *)(&addr), sizeof(struct sckaddr))<0)
    {
        printf("连接失败!\n");
        return;
    }
    else
    {
        printf("连接成功!\n");
    }
    return 0;
}

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

猜你喜欢

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