服务器开发 Socket 相关函数

Socket 函数

#include <sys/types.h> 
#include <sys/socket.h>
int socket(int domain, int type, int protocol)

domain:
AF_INET 这是大多数用来产生 socket 的协议,使用TCP或UDP来传输,用IPv4的地址
AF_INET6 与上面类似,不过是来用IPv6的地址
AF_UNIX 本地协议,使用在Unix和Linux系统上,一般都是当客户端和服务器在同一台及其上的时候使用
type:
SOCK_STREAM 这个协议是按照顺序的、可靠的、数据完整的基于字节流的连接。这是一个使用最多的 socket 类型,这个socket是使用TCP来进行传输。
SOCK_DGRAM 这个协议是无连接的、固定长度的传输调用。该协议是不可靠的,使用 UDP 来进行它的连接。
SOCK_SEQPACKET 该协议是双线路的、可靠的连接,发送固定长度的数据包进行传输。必须把这个包完整的接受才能进行读取。
SOCK_RAW socket 类型提供单一的网络访问,这个socket类型使用ICMP公共协议。(ping、 traceroute使用该协议)
SOCK_RDM 这个类型是很少使用的,在大部分的操作系统上没有实现,它是提供给数据链路层使用,不保证数据包的顺序
protocol:
传0表示使用默认协议。
返回值:
成功:返回指向新创建的 socket 的文件描述符;失败:返回-1,设置errno

socket()打开一个网络通讯端口,如果成功的话,就像 open() 一样返回一个文件描述符,应用程序可以像读写文件一样用 read/write 在网络上收发数据,如果 socket() 调用出错则返回 -1
对于 IPv4,domain 参数指定为 AF_INET
对于TCP 协议,type参数指定为 SOCK_STREAM,表示面向流的传输协议。
如果是 UDP 协议,则 type 参数指定为 SOCK_DGRAM,表示面向数据报的传输协议。
protocol参数的介绍从略,指定为0即可。

bind 函数

#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

sockfd:socket 文件描述符;
addr:构建出 IP 地址加端口号;
addrlen:sizeof(addr) 长度;
返回值:成功返回 0,失败返回 -1,设置 errno。

服务器程序所监听的网络地址和端口号通常是固定不变的,客户端程序得知服务器程序的地址和端口号后就可以向服务器发起连接,因此服务器需要调用bind绑定一个固定的网络地址和端口号。

bind()的作用是将参数sockfdaddr绑定在一起,使sockfd这个用于网络通讯的文件描述符监听addr所描述的地址和端口号。
struct sockaddr * 是一个通用指针类型,addr参数实际上可以接受多种协议的sockaddr结构体,而它们的长度各不相同,所以需要第三个参数addrlen指定结构体的长度。如:

struct sockaddr_in servaddr;
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(666);

首先将整个结构体清零,然后设置地址类型为AF_INET, 网络地址为INADDR_ANY, 这个宏表示本地的任意IP地址,因为服务器可能有多个网卡,每个网卡也可能绑定多个 IP 地址, 这样设置可以在所有的IP地址上监听,直到与某个客户端建立了连接时才确定下来到底用哪个IP地址,端口号为666。

listen 函数

#include <sys/types.h>\
#include <sys/socket.h>
int listen(int sockfd, int backlog);

sockfd:socket 文件描述符;
bocklog:在 Linux 系统中,它是指排队等待建立三次握手队列长度。

查看系统默认 backlog

cat /proc/sys/net/ipv4/tcp_max_syn_backlog

在这里插入图片描述
典型的服务器程序可以同时服务于多个客户端,当有客户端发起连接时,服务器调用的accep()返回并接受这个连接,如果有大量的客户端发起连接而服务器来不及处理,尚未accept 的客户端就处于等待状态,listen() 声明 sockfd 处于监听状态,并且最多允许有 backlog 个客户端处于连接状态,如果接收到更多的连接请求就忽略。listen()成功返回0,失败返回-1

可以改变系统限制的 backlog 大小:

vim /etc/sysctl.conf最后添加:
net.core.somaxconn = 1024
net.ipv4.tcp_max_syn_backlog = 1024保存,然后执行:
sysctl -p

accept 函数

#include <sys/types.h>
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

sockfd:文件描述符
addr:传出参数,返回连接客户端地址信息,含IP地址和端口号
addrlen:传入传出参数(值-结果),传入sizeof(addr)大小,函数返回时返回真正接收到地址结构体的大小。
返回值:成功返回一个新的socket文件描述符,用于和客户端通信,失败返回-1,设置errno

三次握手完成后,服务器调用 accept() 接收连接,如果服务器调用 accept() 时还没有客户端的连接请求,就阻塞等待直到有客户端连接上来。addr 是一个传出参数,accpet() 返回时传出客户端的地址和端口号。addrlen 参数是一个传入传出参数(value-result argument),传入的是调用者提供的缓冲区 addr 的长度以避免缓冲区溢出问题,传出的是客户端地址结构体的实际长度(有可能没有沾满调用者的缓冲区)。如果给 addr 参数传入 NULL,表示不关心客户端的地址。

while(1){cliaddr_len = sizeof(cliaddr);connfd = accept(listenfd, (struct sockaddr *)&ccliaddr, &cliaddr_len);n = read(connfd, buf, MAXLINE);...close(connfd);
}

整个是一个while死循环,每次循环处理一个客户端连接。由于 cliaddr_len 是传入传出参数,每次调用 accept() 之前应该重新赋初值。accept() 的参数 listenfd是先前的监听文件描述符,而 accept() 的返回值是另外一个文件描述符 connfd,之后与客户端之间就通过这个connfd 通讯,最后关闭 connfd 断开连接,而不关闭 listenfd,再次回到循环开头 listenfd,仍然用作accept 的参数。accept()成功返回一个文件描述符,出错返回-1

connect 函数

#include "sys/types.h"
#include "sys/socket.h"
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

sockfd:socket 文件描述符;
addr:传入参数,指定服务器端地址信息,含IP地址和端口号;
返回值:成功返回 0,失败返回 -1, 设置 errno。

客户端需要调用 connect() 连接服务器,connectbind 的参数形式一致,区别在于 bind 的参数是自己的地址,而 connect 的参数是对方的地址。connect 成功返回 0,出错返回 -1

出错处理函数

系统函数调用不能保证每次都成功,必须进行出错处理,这样一方面可以保证程序逻辑正常,另一方面 可以迅速得到故障信息。

#include <errno.h>
#include <string.h>
char *strerror(int errnum);

errnum:传入参数,错误编号的值,一般取 errno 的值
返回值:错误原因

#include <stdio.h>
#include <errno.h>
void perror(const char *s);

s:传入参数,自定义的描述
返回值:无
向标准出错 stderr 输出错误原因。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/803018.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ChatGPT革新学术论文写作:超越传统写作模式

ChatGPT无限次数:点击直达 html ChatGPT革新学术论文写作&#xff1a;超越传统写作模式 随着人工智能技术的日益发展&#xff0c;自然语言生成模型(ChatGPT)在学术论文写作领域扮演着越来越重要的角色。本文将深入探讨ChatGPT如何革新学术论文写作&#xff0c;超越传统写作…

Linux内核自带的 LED 灯驱动实验:创建Led设备节点

一. 简介 前面几篇文章学习了Linux内核自带的 LED 灯驱动&#xff0c;一篇文章分析了驱动与LED设备匹配的关键&#xff0c;一篇文章通过内核配置界面使能了Linux内核自带的 LED 灯驱动。文章如下&#xff1a; Linux内核自带的LED灯驱动框架&#xff1a;驱动与设备匹配分析-CS…

Rabbitmq怎么保证消息的可靠性?

1.消费端消息可靠性保证&#xff1a; 1.消息确认&#xff08;Acknowledgements&#xff09;&#xff1a; 消费者在接收到消息后&#xff0c;默认情况下RabbitMQ会自动确认消息&#xff08;autoAcktrue&#xff09;。为保证消息可靠性&#xff0c;可以设置autoAckfalse&#xf…

Python高级

不定长参数 位置不定长参数&#xff0c;获取参数args会整合为一个元组 def info(*args):print(arg is, args)print(type(arg) is, type(args))info(1, 2, 3, 4, a, b)# 输出 # arg is (1, 2, 3, 4, a, b) # type(arg) is <class tuple> 关键字不定长参数&#xff0c;&…

蓝桥杯2023年第十四届省赛真题-棋盘

solution1(暴力) 暴力蓝桥杯可以过&#xff0c;虽然理论上会超时~ #include<iostream> using namespace std; const int maxn 2010; int a[maxn][maxn] {0};//0白棋&#xff0c;1黑棋 int main(){int n, m, x1, x2, y1, y2;scanf("%d%d", &n, &m)…

一文读懂,SSL证书怎么做验证?

SSL证书目前已经有越来越多的企业网站开始使用&#xff0c;安装SSL证书后&#xff0c;原有的http协议将会变成安全性更好的https加密协议&#xff0c;这对保护用户的信息安全&#xff0c;保障企业及用户的利益起着重要作用。 一张SSL证书的获取&#xff0c;需要经历不少环节&a…

可视化大屏 附源码(Vue3 + TS + DataV + ECharts)

目录 前言 ✨项目代码 1、带有node_modules的项目包 &#x1f680; 2、不带有node_modules的项目包 &#x1f680; ⚒️项目屏幕大小调整 &#x1f48e; 使用开源项目 1、DataV &#x1f530; 2、Echarts &#x1f530; 3、PPchart &#x1f530; 4、表格平滑滚动 &a…

改写yolov5 tag2.0中detect.py便于结合使用

目录 detect.pydetect.py if __name__ == __main__:parser = argparse.ArgumentParser()parser.add_argument(--weights, nargs=+, type=str, default=weights/license50.pt, help=model.pt path(s))parser.add_argument(--source, type=str, default=inference/images, help=…

面了钉钉搜广增算法岗(暑期实习),秒挂。。。。

节前&#xff0c;我们星球组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂朋友、参加社招和校招面试的同学&#xff0c;针对算法岗技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备、面试常考点分享等热门话题进行了深入的讨论。 汇总…

C# 如何修改项目名称

目录 背景具体步骤1、Visual Studio中修改项目名和程序集名称以及命名空间2、修改项目文件夹名3、修改解决方案里项目的路径4、再次打开解决方案&#xff0c;问题解决步骤总结 名词解释解决方案&#xff08;Solution&#xff09;项目&#xff08;Project&#xff09;程序集&…

sa-token非Web上下文无法获取Request

0x02 非Web上下文无法获取Request 问题定位 在我们使用sa-token安全框架的时候&#xff0c;有时候会提示&#xff1a;SaTokenException:非Web上下文无法获取Request 错误截图&#xff1a; 在官方网站中&#xff0c;查看常见问题排查&#xff1a; 非Web上下文无法获取Reques…

网络工程师练习题(11)

网络工程师 所示的调制方式是DPSK&#xff0c;若数据速率为1Kb/s&#xff0c;则载波速率为2000Hz。EL载波的子信道速率为64Kb/s。100Base-T4采用的编码技术为8B/6T&#xff0c;利用UTP-3传输介质进行数据传输。在异步通信中&#xff0c;每个字符包含1为起始、8位数据位、1位奇偶…

运行游戏找不到steam_api64.dll怎么办?steam_api64.dll丢失解决方法

steam_api64.dll是64位Windows操作系统上的一个动态链接库&#xff08;DLL&#xff09;文件&#xff0c;其大小通常在1.5-3.5 MB之间。这个文件对于Steam平台至关重要&#xff0c;因为它实现了游戏验证、更新等功能&#xff0c;并确保了用户拥有游戏的合法使用权。它通过提供一…

基于单片机水塔水位检测控制系统设计

**单片机设计介绍&#xff0c; 基于单片机水塔水位检测控制系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机水塔水位检测控制系统设计的主要目标是实现水塔水位的自动监测与控制&#xff0c;确保水塔内的水位始…

大模型从入门到应用——OpenAI基础调用

摘要&#xff1a;这是OpenAI的基本调用&#xff0c;通过文章了解大模型的一个基础使用 1. 调用说明 在大型语言模型&#xff08;LLM&#xff09;的应用中&#xff0c;OpenAI的基础调用是入门的关键一步。通过调用OpenAI的API&#xff0c;我们可以利用其强大的语言处理能力&am…

在 Python 中使用 Turtle 绘制 26 个英文字母

以下是使用 turtle 模块在 python 中绘制所有 26 个英文字母的代码&#xff0c;字母大小并不统一&#xff0c;旨在为初学者提供 turtle 的基本使用方法。 # 字母 A import turtle tturtle.Turtle() t.penup() t.goto(-30,50) t.pendown() t.pensize(10) t.pencolor("blac…

雷军给年轻人的五点建议

前言 拿来激励自己,没事就看一看,给自己高一点的要求. 致刚入门的程序员五点建议 每个IT企业&#xff0c;尤其是初创企业&#xff0c;非常苦恼&#xff1a;找不到好的程序员。现在大学、软件学院及各种培训机构&#xff0c;每年培养几十万的程序员&#xff0c;毕业的每个人都…

网页版五子棋对战实现和自动化测试

文章目录 前言一、项目描述项目演示链接 二、实现的功能与操作1.登录注册2.游戏大厅线程安全问题多开处理 3.五子棋对战 三、项目测试1.测试用例2.测试技术点3.部分测试用例展示&#xff08;1&#xff09;注册页面&#xff08;2&#xff09;登录页面&#xff08;3&#xff09;游…

生成式AI:最有商业前景的人工智能技术,不再是改变分发关系,而是升级生产力

根据最新的报告可以看出ChatGPT到底有多厉害&#xff0c;多个方面实现从判别决策到创造生成 生成式AI VS Web 3.0 &#xff1a;不追求生产关系的重塑&#xff0c;但将大幅度提升和创造生产力 创造是生成式AI的核心&#xff0c;本质是对生产力的大幅度提升和创造。生成式AI通过…

2、java语法之循环、数组与方法(找工作版)

写在前面&#xff1a;整个系列文章是自己学习慕课相关视频&#xff0c;进行的一个总结。文章只是为了记录学习课程的整个过程&#xff0c;方便以后查漏补缺&#xff0c;找到对应章节。 文章目录 一、Java循环结构1、while循环2、do-while循环3、for循环4、嵌套循环5、break语句…