c++ socket、 listen、accept、recv 、send、 connect函数记录

这篇具有很好参考价值的文章主要介绍了c++ socket、 listen、accept、recv 、send、 connect函数记录。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

socket

int socket (int __domain, int __type, int __protocol);
  1. __domain为协议域,又称协议族,我们最常用的有AF_INET、AF_INET6(也可以写作为PF_INET、PF_INET6),分别代表IPv4地址和IPv6地址。

  2. __type为数据传输方式或套接字类型,最常见的有SOCK_STREAM和 SOCK_DGRAM,其中SOCK_STREAM为面向连接的数据传输方式,是基于TCP的协议,数据可以准确无误地到达另一台计算机,如果损坏或丢失,可以重新发送,但效率相对较慢;而SOCK_DGRAM是无连接的数据传输方式,是基于UDP的协议,即只管传输数据,不作数据校验,如果数据在传输中损坏,或者没有到达另一台计算机,是没有办法补救的。

  3. __protocol为传输协议,对应上述的__type,常用的有IPPROTO_TCP 和 IPPTOTO_UDP分别代表TCP和UDP协议。而系统会根据__type的值自行选择,因此该项一般可直接指定为0。

  4. socket返回的值是一个文件描述符,由于0,1,2,都被占用,所以是从3开始,错误时返回-1;

bind()和connect()函数

bind()函数用于服务器端,用来绑定套接字和自己的ip地址和端口;
connect()函数用于客户端,旨在连接套接字和服务器端的IP地址和端口。
两个函数的返回值表示是否成功(0表示成功,-1表示错误)
函数原型如下:

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
  1. sockfd为socket返回的文件描述符。

  2. addr为一个const struct sockaddr *指针,由于兼容性的原因,这里我们只能先使用sockaddr_in 结构体来定义相应的IP地址和端口号,然后再强制转换为 sockaddr 类型的方式。

  3. addrlen为2中结构体的大小,可由sizeof()计算给出。

在使用上述两个函数之前,需要先给sockaddr_in 结构体中的成员赋值,其中sockaddr_in 结构体的成员变量如下:

struct sockaddr_in{
    sa_family_t     sin_family;   //协议族,和socket()函数中一致即可
    uint16_t        sin_port;     //16位的端口号,尽量保证端口号在1024~65536之间
    struct in_addr  sin_addr;     //32位IP地址
    char            sin_zero[8];  //不使用,一般用0填充
};

listen()和accept()函数

在服务器端,绑定了套接字后,还需通过listen()函数进入到监听状态。
监听状态下调用accept()函数进行接收,当收到来自客户端的请求后就可以建立连接了。
listen()函数返回值0表示成功,-1表示失败

int listen(int __fd, int __n);
  1. __fd为socket返回的文件描述符。

  2. __n为请求队列的最大长度,也即缓冲区大小。当socket正在处理客户端请求时,如果有新的请求到来,只能被放进缓冲区,这个参数就是表明能接受多少个客户端请求。

accept()函数返回一个新的文件描述符,表示和对应的客户端进行通信。

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
  1. __fd为socket返回的文件描述符。

  2. addr为一个const struct sockaddr *指针,由于兼容性的原因,这里我们只能先使用sockaddr_in 结构体来定义相应的IP地址和端口号,然后再强制转换为 sockaddr 类型的方式。

  3. addrlen为一个指针,解引用后值为2中结构体的大小,可由sizeof()计算给出。

send()、recv()、read()和write()函数

send()和write()返回值为向fd写入的字节数,=0时断开连接,<0时出错。
recv()和read()返回值为从fd读取的字节数,=0时断开连接或读取结束,<0时出错。

ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void*buf,size_t nbytes);
  • read:负责从描述符fd中读取内容,当读取成功时,read返回实际所读的字节数(大于0);如果返回的值为0,表示已经读到文件结束了;如果返回的值小于0,则出现错误,如果错误为EINTR,说明错误是由中断引起的,如果是ECONNREST表示网络连接出了问题。

  • write:将buf中的nbytes字节内容写入到文件描述符fd,成功时返回写的字节数,失败的时候返回-1;在实际的程序中,写入有两种可能:

    • write的返回值大于0,表示写了部分或者是全部的数据。这样我们用一个while循环来不停的写入,但是循环过程中的buf参数和nbyte参数得由我们来更新。也就是说,网络写函数是不负责将全部数据写完之后在返回的。
    • 返回的值小于0,此时出现了错误。我们要根据错误类型来处理.如果错误为EINTR表示在写的时候出现了中断错误。如果为EPIPE表示网络连接出现了问题(对方已经关闭了连接).
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);

第四个参数可以是

flags 描述
MSG_DONTROUTE 不查找表
MSG_OOB 接受或者发送带外数据
MSG_PEEK 查看数据,并不从系统缓冲区移走数据
MSG_WAITALL 等待所有数据

当recv/send的flag参数设置为0时,则和read/write是一样的。
如果有如下几种需求,则read/write无法满足,必须使用recv/send:文章来源地址https://www.toymoban.com/news/detail-426072.html

  • 为接收和发送进行一些选项设置
  • 从多个客户端中接收报文
  • 发送带外数据(out-of-band data)

TCP客户端

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include<netdb.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<arpa/inet.h>

using namespace std

到了这里,关于c++ socket、 listen、accept、recv 、send、 connect函数记录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MPI之MPI_Send&MPI_Recv阻塞接口及参数详解

    MPI简介以及阻塞非阻塞代码示例 MPI_Send buf:指向发送缓冲区的指针; count:发出的消息的数量(例如,整数个数、字节数等); datatype:发出消息的数据类型。MPI 数据类型通常是针对特定的数据结构(如 char、int、float 等)定义的,它仅能在使用相同 MPI_Datatype 的进程间传递

    2024年02月11日
    浏览(41)
  • 【Socket】Linux下UDP Socket的基本流程以及connect、bind函数的使用(C语言实现)

    Socket的原意是“插座”,在计算机通信领域,socket 被翻译为“套接字”。 Socket通信主要有两个类型:TCP、UDP。 TCP通信,是一个有序的、可靠的、面向连接的通信方式。用数据流的方式传递信息。 UDP通信,是无连接的、不保证有序到达的、但具有较好的实时性、能够高速传输

    2024年02月13日
    浏览(33)
  • github Recv failure: Connection reset by peer

    晚上敲着代码准备提交,执行 git pull ,报错 Recv failure: Connection reset by peer 。看着这报错我陷入了沉思,这个报错在我的理解中被被人拒绝了。查了一下资料,发现这个报错是 http 系列的问题,于是我有了想法。。 没啥问题 也没啥问题 没错,是 http 的。那我把他改成 git 会咋

    2024年02月13日
    浏览(41)
  • docker (56) Recv failure: Connection reset by peer

    docker 运行一个spring boot的api接口项目,在虚拟机上测试: curl 127.0.0.1:9997/doc.html   报错:(56) Recv failure: Connection reset by peer 在网上搜了很多包括: systemctl status firewalld  检查防火墙状态 systemctl disable firewalld  永久关闭防火墙 输入命令:sysctl net.ipv4.ip_forward 如果返回为“net.i

    2024年02月22日
    浏览(47)
  • 【完美解决】GitHub连接超时问题 Recv failure: Connection was reset

    已经开了梯子但是在Idea中使用git(GitHub)还是连接超时 Recv failure: Connection was reset 。此时需要让git走代理。 1.对右下角网络点击右键 - 打开 网络和Internet设置 2. 代理 - 查看到地址和端口号 127.0.0.1:7890 3.在终端(cmd)输入命令 4.查看是否设置成功 至此完成 相当丝滑 ^ ^

    2024年02月08日
    浏览(40)
  • RPC failed; curl 56 Recv failure: Connection was reset.

    RPC failed; curl 56 Recv failure: Connection was reset. 网络问题。 http缓存不够或者网络不稳定等 修改git配置(加大httpBuffer) 即可。 记录错误,后期要是在遇到。 链接: 参考.

    2024年02月11日
    浏览(50)
  • curl网络访问时报错:(56) Recv failure: Connection timed out

    某次用户对接某业务平台,在用户侧curl平台侧资源,报错:(56) Recv failure: Connection timed out; 1、在服务器端curl上述地址正常;公网访问该url地址也正常; 2、用户侧访问,telnet 端口访问正常,这是curl Url时,提示连接超时; 3、可能原因: 客户端侧查看socket:显示:ESTABLISH

    2024年02月05日
    浏览(47)
  • windows启动Redis报错: Could not create server TCP listening socket *:6379: listen: 提供了一个无效的参数

    问题: windows系统,redis一直正常使用,早上重启电脑后,点击redis-server闪一下无法启动。  使用命令行启动报如下错:  网上查找解决方案: 1、多数文章提示的思路都是 6379 端口 被占用,找到相应进程然后 kill 该进程,用 netstat -aon|findstr \\\"6379\\\" ,没有找到占用该端口的进程

    2024年01月24日
    浏览(52)
  • [解决Github 克隆错误] unable to access ‘xxx‘: Recv failure: Connect

    1.错误描述: 从GitHub上克隆仓库到本地,出现错误: unable to access \\\'https://github.com/xxxx\\\': Recv failure: Connection was reset。  克隆失败。 2.第一次解决此问题 :从终端输入:  git config --global http.sslVerify \\\"false\\\" 再此运行克隆代码,出现新的错误。443网络错误。  3. 大多数人到第二步就

    2024年02月16日
    浏览(54)
  • curl: (56) Recv failure: Connection reset by peer问题汇总和解决方案

    这两天正在学习用docker制作tomcat镜像,有一个问题困扰了我3天,可能大家在学习时也会遇到,于是我就单独发一篇文章来解决这个问题。 解决办法我在上一篇文章 Docker进阶篇之DockerFile制作Tomcat镜像,教你如何发布镜像到DockerHub和阿里云 已经详细说明了,这里再说明一次。

    2024年02月01日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包