欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

介绍用于套接字编程的主要 API 函数(某马)

最编程 2024-07-09 14:52:55
...

1.socket函数

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

    • 函数描述: 创建socket

    • 参数说明:

      • domain: 协议版本

        • AF_INET: IPV4

        • AF_INET6: IPV6

        • AF_UNIX AF_LOCAL:本地套接字使用

      • type:协议类型

        • SOCK_STREAM 流式, 默认使用的协议是TCP协议

        • SOCK_DGRAM 报式, 默认使用的是UDP协议

      • protocal:

        • 一般填0, 表示使用对应类型的默认协议.
      • 返回值:

        • 成功: 返回一个大于0的文件描述符

        • 失败: 返回-1, 并设置errno

  • 当调用socket函数以后, 返回一个文件描述符, 内核会提供与该文件描述符相对应的读和写缓冲区, 同时还有两个队列, 分别是请求连接队列和已连接队列.

2.bind函数

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

    • 函数描述: 将socket文件描述符和IP,PORT绑定

    • 参数说明:

      • socket: 调用socket函数返回的文件描述符

      • addr: 本地服务器的IP地址和PORT,

        • struct sockaddr_in serv;

        • serv.sin_family = AF_INET;

        • serv.sin_port = htons(8888);

        • //serv.sin_addr.s_addr = htonl(INADDR_ANY);

        • //INADDR_ANY: 表示使用本机任意有效的可用IP

        • inet_pton(AF_INET, "127.0.0.1", &serv.sin_addr.s_addr);

      • addrlen: addr变量的占用的内存大小

    • 返回值:

      • 成功: 返回0

      • 失败: 返回-1, 并设置errno

3.listen函数

  • int listen(int sockfd, int backlog);

    • 函数描述: 将套接字由主动态变为被动态

    • 参数说明:

      • sockfd: 调用socket函数返回的文件描述符

      • backlog: 同时请求连接的最大个数(还未建立连接)

    • 返回值:

      • 成功: 返回0

      • 失败: 返回-1, 并设置errno

4. accept函数
  • int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

    • 函数说明:获得一个连接, 若当前没有连接则会阻塞等待.

    • 函数参数:

      • sockfd: 调用socket函数返回的文件描述符

      • addr: 传出参数, 保存客户端的地址信息

      • addrlen: 传入传出参数, addr变量所占内存空间大小

    • 返回值:

      • 成功: 返回一个新的文件描述符,用于和客户端通信

      • 失败: 返回-1, 并设置errno值.

  • accept函数是一个阻塞函数, 若没有新的连接请求, 则一直阻塞.

  • 从已连接队列中获取一个新的连接, 并获得一个新的文件描述符, 该文件描述符用于和客户端通信. (内核会负责将请求队列中的连接拿到已连接队列中)

5.connect函数

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

    • 函数说明: 连接服务器

    • 函数参数:

      • sockfd: 调用socket函数返回的文件描述符

      • addr: 服务端的地址信息

      • addrlen: addr变量的内存大小

    • 返回值:

      • 成功: 返回0

      • 失败: 返回-1, 并设置errno值



接下来就可以使用write和read函数进行读写操作了.

除了使用read/write函数以外, 还可以使用recv和send函数

6.读取数据和发送数据:

ssize_t read(int fd, void *buf, size_t count);

ssize_t write(int fd, const void *buf, size_t count);

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

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

对应recv和send这两个函数flags直接填0就可以了.

注意: 如果写缓冲区已满, write也会阻塞, read读操作的时候, 若读缓冲区没有数据会引起阻塞.

使用socket的API函数编写服务端和客户端程序的步骤图示:

根据服务端和客户端编写代码的流程, 编写代码并进行测试.

测试过程中可以使用netstat命令查看监听状态和连接状态

netstat命令:

a表示显示所有,

n表示显示的时候以数字的方式来显示

p表示显示进程信息(进程名和进程PID)

作业:

自己编写代码熟悉一下服务端和客户端的代码开发流程;

设计服务端和客户端通信协议(属于业务层的协议)

如发送结构体

typedef struct teacher_{

int tid;

char name[30];

int age;

char sex[30];

int sal;

} teacher;

typedef struct student_{

int sid;

char name[30];

int age;

char sex[30];

}student;

typedef struct SendMsg_{

int type;//1 - teacher;2 - student

int len;//

char buf[0];//变长发送数据

}SendMsg;

推荐阅读