socket 编程快速步骤

本文详细介绍了TCP服务器如何处理客户端连接的步骤,包括调用socket()创建套接字、bind()绑定IP和端口、listen()进入监听状态、accept()接受连接请求、使用recv/send进行通信,以及最后调用close()关闭套接字。这个过程是所有基于TCP协议的服务器端程序的基础,涉及网络编程的关键操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

为了能够正常让客户端能正常连接到服务器,服务器必须遵循以下处理流程:
①、调用 socket()函数打开套接字,得到套接字描述符;
②、调用 bind()函数将套接字与 IP 地址、端口号进行绑定;
③、调用 listen()函数让服务器进程进入监听状态;
④、调用 accept()函数获取客户端的连接请求并建立连接;
⑤、调用 read/recv、 write/send 与客户端进行通信;
⑥、调用 close()关闭套接字。
 

0.首先调用头文件

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

1.使用socket()函数,产生TCP套接字
 

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


socket()函数类似于open()函数,它用于创建一个通信端点,如果成功则返回一个网络文件描述符。参数 domain 用于指定一个通信域,用来选择协议簇。其中选择AF_INET代表IPV4。参数 type 指定套接字的类型,SOCK_STREAM代表TCP协议,SOCK_DGRAM代表UDP协议。参数 protocol 通常设置为 0。

int socket_fd = socket(AF_INET, SOCK_STREAM, 0);//打开套接字
if (0 > socket_fd) {
    perror("socket error");
    exit(-1);
}

2.bind()函数
bind()函数用于将一个 IP 地址或端口号与一个套接字进行绑定

    struct sockaddr_in server; //服务器端和客户端IPV4地址信息

    //初始化server套接字地址结构
    bzero(&server, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_port = htons(PORT);
    server.sin_addr.s_addr = htonl(INADDR_ANY);
    
    //使用bind()函数,将套接字与指定的协议地址绑定
    if(bind(listenfd, (struct sockaddr *)&server, sizeof(server)) == -1)
    {
        perror("Bind() error");
        exit(1);
    }

3.listen()函数
        listen()函数只能在服务器进程中使用,让服务器进程进入监听状态,等待客户端的连接请求, listen()函数在一般在 bind()函数之后调用,在 accept()函数之前调用,它的函数原型是:

int listen(int sockfd, int backlog);

        无法在一个已经连接的套接字(即已经成功执行 connect()的套接字或由 accept()调用返回的套接字)上执行 listen()。

4.accept()函数
        accept()函数为阻塞函数,会等待客户端连接的到来。

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

        当有客户端连接请求到达时, accept()函数与远程客户端之间建立连接, accept()函数返回一个新的套接字。这个套接字与 socket()函数返回的套接字并不同, socket()函数返回的是服务器的套接字(以服务器为例),而accept()函数返回的套接字连接到调用 connect()的客户端,服务器通过该套接字与客户端进行数据交互,譬如向客户端发送数据、或从客户端接收数据。
        所以,理解 accept()函数的关键点在于它会创建一个新的套接字,其实这个新的套接字就是与执行connect()(客户端调用 connect()向服务器发起连接请求)的客户端之间建立了连接,这个套接字代表了服务器与客户端的一个连接。如果 accept()函数执行出错,将会返回-1,并会设置errno 以指示错误原因。参数 addr 是一个传出参数,参数 addr 用来返回已连接的客户端的 IP 地址与端口号等这些信息。参数addrlen 应设置为 addr 所指向的对象的字节长度,如果我们对客户端的 IP 地址与端口号这些信息不感兴趣,可以把 arrd 和 addrlen 均置为空指针 NULL。

5.recv()函数
recv()函数默认为阻塞函数

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

        不论是客户端还是服务器都可以通过 revc()函数读取网络数据。参数sockfd 指定套接字描述符,参数 buf 指向了一个数据接收缓冲区,参数 len 指定了读取数据的字节大小,参数 flags 可以指定一些标志用于控制如何接收数据。

6.send()函数

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

参数sockfd 指定套接字描述符,参数 buf 指向了一个数据接收缓冲区,参数 len 指定了读取数据的字节大小,参数 flags 指定一些标志来改变处理传输数据的方式,默认为0。
7.close()关闭套接字

close(int sockfd);

        当不再需要套接字描述符时,可调用 close()函数来关闭套接字,释放相应的资源。注意这个套接字是accept()函数返回的套接字。

8.connect()函数

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

        该函数用于客户端应用程序中,客户端调用 connect()函数将套接字 sockfd 与远程服务器进行连接,参数 addr 指定了待连接的服务器的 IP 地址以及端口号等信息,参数 addrlen 指定了 addr 指向的 struct sockaddr对象的字节大小。
        客户端通过 connect()函数请求与服务器建立连接,对于 TCP 连接来说,调用该函数将发生 TCP 连接的握手过程,并最终建立一个 TCP 连接,而对于 UDP 协议来说,调用这个函数只是在sockfd 中记录服务器IP 地址与端口号,而不发送任何数据。
        函数调用成功则返回 0,失败返回-1,并设置 errno 以指示错误原因。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值