首页 > 运维 > linux运维 > 正文

send()、sendto()和recv()、recvfrom()的使用

看不見的法師
发布: 2025-07-15 10:50:01
原创
330人浏览过

大家好,又见面了,我是你们的朋友全栈君。

在UDP通信中,sendto()函数需要在参数中指定接收方的地址/端口,而recvfrom()函数则在参数中存放发送方的地址/端口。相比之下,send()和recv()函数不需要这样做,但在调用send()之前,必须为套接字指定接收方的地址/端口(这样该函数才知道要把数据发往哪里)。在调用recv()之前,可以为套接字指定发送方的地址/端口,这样该函数就只接收指定发送方的数据;当然,若不指定,也可以接收任意地址的数据。(这些内容在之前关于UDP通信中connect()和bind()函数的文章中有详细介绍。)

这四个函数的使用相对简单,但在某个实例中,我遇到了一个小问题。实现的功能是:UDP服务器创建一个套接字接收客户端的连接,连接成功后,服务器再创建一个套接字与客户端进行数据交互,要求尽量使用connect()、recv()和send()函数。

UDP服务器代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys>
#include <sys>
#include <netinet>
#include <arpa>
#define BUFSZ 1024
#define PORT 6567

int main(void) {
    int srv_sd, cli_sd;
    int new_sd;
    int ret;
    struct sockaddr_in svr_addr, cli_addr;
    socklen_t addrlen = sizeof(struct sockaddr_in);
    char buf[BUFSZ] = {};

    // 创建套接字
    if ((srv_sd = socket(AF_INET, SOCK_DGRAM, 0)) 
登录后复制

UDP客户端代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys>
#include <sys>
#include <netinet>
#include <arpa>
#define BUFSZ 1024
#define PORT 6567

int main(int argc, char *argv[]) {
    int sd;
    struct sockaddr_in svr_addr, cli_addr;
    int ret;
    socklen_t addrlen = sizeof(struct sockaddr_in);
    char buf[BUFSZ] = {};

    // 创建套接字
    if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) 
登录后复制

运行结果:

send()、sendto()和recv()、recvfrom()的使用send()、sendto()和recv()、recvfrom()的使用send()、sendto()和recv()、recvfrom()的使用

观察程序流程,可以得出:

send()、sendto()和recv()、recvfrom()的使用

SpeakingPass-打造你的专属雅思口语语料
SpeakingPass-打造你的专属雅思口语语料

使用chatGPT帮你快速备考雅思口语,提升分数

SpeakingPass-打造你的专属雅思口语语料 25
查看详情 SpeakingPass-打造你的专属雅思口语语料

客户端发起连接给服务器,服务器接收到后创建新的套接字并调用connect()函数为该套接字指定目标地址信息。这个目标地址信息虽然确实是客户端的,但客户端的目标地址却是服务器,那么服务器新的套接字的目标地址不是客户端而是服务器,因此服务器发出的数据还是自己收到。

程序的问题出现在客户端。客户端创建了套接字后,就立即为其指定目标(服务器)的地址信息,而这个目标地址信息并非作为接下来数据交互的地址。因此,应该把为客户端指定目标地址的操作放在服务器创建新的套接字后返回数据到客户端之后。但注意,客户端创建完套接字后不能马上使用connect()来指定目的地址信息,那么在发送数据给服务器时就需要使用sendto(),接收数据时则使用recvfrom()。流程图应改为:

send()、sendto()和recv()、recvfrom()的使用

客户端代码实现为:

int main(int argc, char *argv[]) {
    int sd;
    struct sockaddr_in svr_addr, cli_addr;
    int ret;
    socklen_t addrlen = sizeof(struct sockaddr_in);
    char buf[BUFSZ] = {};

    // 创建套接字
    if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) 
登录后复制

运行结果:

send()、sendto()和recv()、recvfrom()的使用

结论:connect()、send()和recv()三个函数的搭配使用并不能说一定能代替sendto()和recvfrom(),具体使用还要依据代码场景。

发布者:全栈程序员栈长,转载请注明出处:https://www.php.cn/link/592f69eb8605faf19bb15d0b370cfac8 原文链接:https://www.php.cn/link/c8377ad2a50fb65de28b11cfc628d75c

以上就是send()、sendto()和recv()、recvfrom()的使用的详细内容,更多请关注php中文网其它相关文章!

相关标签:
最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号