📜  计算机网络中的套接字(1)

📅  最后修改于: 2023-12-03 14:57:32.950000             🧑  作者: Mango

计算机网络中的套接字

计算机网络中的套接字(Socket)是一种用于网络通信的编程接口,它提供了一种标准的接口,方便不同的程序在多台计算机之间进行通信。套接字常被用于基于网络的应用程序中,如客户端/服务器模型,以及P2P网络等。

套接字类型

套接字通常分为两种类型:

  • 流套接字(SOCK_STREAM),基于TCP协议,提供面向连接的可靠的数据传输服务;
  • 数据报套接字(SOCK_DGRAM),基于UDP协议,提供无连接的、不可靠的数据传输服务。
套接字编程

在套接字编程中,程序员通常要进行以下步骤:

创建套接字
#include <sys/socket.h>

int socket(int domain, int type, int protocol);
  • domain:指定套接字的通信域,常用的有AF_INET(IPv4)和AF_INET6(IPv6);
  • type:指定套接字的类型,常用的有SOCK_STREAM和SOCK_DGRAM;
  • protocol:指定通信协议,一般设置为0,表示使用默认协议。

该函数返回一个套接字描述符,调用失败返回-1。

绑定套接字
#include <sys/socket.h>

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
  • sockfd:套接字描述符;
  • addr:指向本地协议地址的结构体指针;
  • addrlen:本地协议地址结构体的长度。

绑定套接字需要指定监听的IP地址和端口号。该函数返回0表示成功,-1表示失败。

监听套接字
#include <sys/socket.h>

int listen(int sockfd, int backlog);
  • sockfd:套接字描述符;
  • backlog:指定连接请求队列的最大长度。

该函数用于TCP服务器,在调用bind()函数之后,使用该函数使套接字进入监听状态,等待客户端的连接请求。该函数返回0表示成功,-1表示失败。

接受连接请求
#include <sys/socket.h>

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
  • sockfd:套接字描述符;
  • addr:指向存放客户端地址的结构体指针;
  • addrlen:指向存放客户端地址结构体长度的变量地址。

该函数用于TCP服务器,在调用listen()函数之后,当有客户端连接请求到来时,使用该函数接受连接请求,并返回一个新的套接字描述符,以供服务器与客户端之间进行通信。该函数返回新套接字描述符,调用失败返回-1。

发起连接请求
#include <sys/socket.h>

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
  • sockfd:套接字描述符;
  • addr:指向远端协议地址的结构体指针;
  • addrlen:远端协议地址结构体的长度。

该函数用于TCP客户端,使用该函数向服务器发起连接请求。该函数返回0表示成功,-1表示失败。

发送和接收数据
#include <sys/socket.h>

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

ssize_t recv(int sockfd, void *buf, size_t len, int flags);
  • sockfd:套接字描述符;
  • buf:指向发送/接收缓冲区的指针;
  • len:发送/接收数据的长度;
  • flags:一些标志位,通常设置为0。

以上两个函数用于发送和接收数据。对于流套接字,调用send()函数可以发送任意长度的数据,调用recv()函数可以接收任意长度的数据;对于数据报套接字,调用send()函数和recv()函数发送和接收数据均需要指定数据的长度。函数返回实际发送/接收的字节数,调用失败返回-1。

关闭套接字
#include <unistd.h>

int close(int fd);
  • fd:套接字描述符。

该函数用于关闭套接字,释放相关的系统资源。调用成功返回0,失败返回-1。

总结

套接字在计算机网络中被广泛应用,通过套接字编程,程序员可以方便地实现基于网络的应用程序。

以上介绍了套接字的基本使用方法,程序员需要根据具体的应用场景,详细了解相关函数的使用方法。