当前位置: 首页 > news >正文

服务器本地搭建

socket函数

它用于创建一个新的套接字(socket)。

函数原型
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
参数解释

domain:它指定了通信所使用的协议族,常见的取值如下:

        AF_INET:代表 IPv4 协议。

        AF_INET6:代表 IPv6 协议。

        AF_UNIXAF_LOCAL:用于本地(Unix 域)套接字通信。

type:它指定了套接字的类型,常用的类型有:

        SOCK_STREAM:表示面向连接的、可靠的 TCP 套接字。

        SOCK_DGRAM:表示无连接的、不可靠的 UDP 套接字。

        SOCK_RAW:允许程序直接访问底层协议,如 IP、ICMP 等。

protocol:通常设置为 0,表示让系统根据domaintype自动选择合适的协议。

返回值

        若函数调用成功,会返回一个新的套接字描述符(非负整数),后续的网络操作会用到这个描述符。

        若调用失败,会返回 -1,并设置errno来指示具体的错误原因。

示例

#include <iostream>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>

using namespace std;

int main()
{
	// 初始化网络 
	int socketfd = socket(AF_INET, SOCK_STREAM, 0);
	if (socketfd < 0)
	{
	    /*可能情况 
		*1、没有连接网络		
		*2、网卡坏了
		*/
		perror("socket error");
	}
	else
	{
		cout << "服务器网络初始化 socketfd=" << socketfd << endl;
	}

	return 0;
}

 结果

 bind函数

        用于将一个套接字(socket)与特定的网络地址和端口号绑定在一起。

函数原型
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
参数解释

        sockfd:这是由socket函数返回的套接字描述符,代表要进行绑定操作的套接字。

        addr:指向一个sockaddr类型的结构体指针,该结构体包含了要绑定的地址和端口信息。不过在实际使用中,通常会使用具体的地址结构体,如struct sockaddr_in(用于 IPv4)或struct sockaddr_in6(用于 IPv6),然后进行强制类型转换。

        addrlen:表示addr所指向的结构体的长度。

补(struct sockaddr_in):

#include <netinet/in.h>

struct sockaddr_in {
    sa_family_t    sin_family;  // 地址族,通常是 AF_INET(IPv4)
    in_port_t      sin_port;    // 端口号,使用网络字节序(大端序)(服务器系统默认IP地址:INADDR_ANY)
    struct in_addr sin_addr;    // IPv4 地址,使用网络字节序
    unsigned char  sin_zero[8]; // 填充字段,使其大小与 struct sockaddr 相同,一般设置为全 0
};

返回值

        若绑定成功,返回 0。

        若失败,返回 -1,并设置errno来指示具体的错误原因。

listen函数

        主要用于将一个套接字(socket)设置为监听状态,以便接收客户端的连接请求。 

函数原型
#include <sys/socket.h>
int listen(int sockfd, int backlog);
参数解释

        sockfd:这是一个由socket函数返回的套接字描述符,代表要设置为监听状态的套接字。该套接字必须已经通过bind函数绑定到了一个特定的地址和端口。

        backlog:指定了允许在队列中等待处理的最大连接请求数量。当有多个客户端同时发起连接请求时,服务器无法立即处理所有请求,这些请求会被放入一个队列中等待处理。backlog的值决定了这个队列的最大长度。不同系统对backlog的最大值有不同的限制,一般来说,常见的值可以设置为 5 或 10

返回值

        若函数调用成功,返回 0。

        若调用失败,返回 -1,并设置errno来指示具体的错误原因。

accept函数 

        主要用于服务器端,它会让服务器处于阻塞状态,等待客户端的连接请求。一旦接收到客户端的连接请求,accept函数就会返回一个新的套接字描述符,这个描述符用于和客户端进行数据通信。而原来的套接字描述符依旧负责监听新的连接请求。

函数原型
#include <sys/socket.h>

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
参数解释

        sockfd:这是一个已经处于监听状态的套接字描述符,它是通过socket()创建,再由bind()绑定地址和端口,最后使用listen()开始监听的套接字。

        addr(前面设置过的化一般为NULL):这是一个指向sockaddr结构体的指针,该结构体用于存储客户端的地址信息。在实际使用时,通常会使用sockaddr_in(用于 IPv4)或sockaddr_in6(用于 IPv6)结构体,然后进行类型转换。

        addrlen(前面设置过的化一般为NULL):这是一个指向socklen_t类型的指针,它表示addr所指向的结构体的长度。在调用accept之前,需要将其初始化为addr结构体的大小;调用完成后,该指针指向的值会被更新为实际存储的客户端地址信息的长度。

返回值

        若调用成功,accept会返回一个新的套接字描述符,此描述符用于和客户端进行数据通信。原来的sockfd仍然用于监听新的连接请求。

        若调用失败,会返回 -1。

整合示例

#include <iostream>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

using namespace std;

int main()
{
	struct sockaddr_in addr;
	int length = 0;
	int acceptfd = 0;
	// 初始化网络 
	int socketfd = socket(AF_INET, SOCK_STREAM, 0);
	if (socketfd < 0)
	{
	    /*可能情况 
		*1、没有连接网络		
		*2、网卡坏了
		*/
		perror("socket error");
		return 0;
	}
	else
	{
		addr.sin_family = AF_INET;
		// 服务器系统默认IP地址
		addr.sin_addr.s_addr = INADDR_ANY;
		addr.sin_port = htons(10001);
		length = sizeof(addr);

		// 绑定端口号
		if (bind(socketfd, (struct sockaddr*)(&addr), length) == -1)
		{
			perror("bind error");
			return 0;
		}

		// 监听这个文件描述符,是否有客户端来连接
		if (listen(socketfd, 10) == -1)
		{
			perror("lister error");
			return 0;
		}

		cout << "服务器网络搭建成功" << endl;

		// 因为服务器24h长时间开机
		while (1)
		{
			// acceptfd代表已经连接成功的客户端
			// 阻塞式函数(等待客户端的到来)
			acceptfd = accept(socketfd, NULL, NULL);
			cout << "客户端上线,acceptfd=" << acceptfd << endl;
		}
	}

	return 0;
}

结果 

相关文章:

  • FPGA_UART
  • 刷题记录(3)C语言中的字符
  • LlamaIndex学习
  • Fiddler为什么可以看到一次HTTP请求数据?
  • 项目班——0408
  • 【神经网络】python实现神经网络(四)——误差反向传播的基础理论
  • AI与我共创WEB界面
  • 风丘年度活动:2025年横滨汽车工程展览会
  • java中常用的集合 - 面试篇
  • 【NIO番外篇】之组件 Selector
  • 【Redis】布隆过滤器应对缓存穿透的go调用实现
  • malloc、operator new、new的关系
  • c语言练习4
  • NO.92十六届蓝桥杯备战|图论基础-最小生成树-Prim算法-Kruskal算法|买礼物|繁忙的都市|滑雪(C++)
  • 常见攻击方式及防范措施
  • 基于PHP的酒店网上订房系统(源码+lw+部署文档+讲解),源码可白嫖!
  • Oracle数据库数据编程SQL<9.3 数据库逻辑备份和迁移Data Pump (EXPDP/IMPDP) 导出、导入补充>
  • 视觉slam框架从理论到实践-第一节绪论
  • C语言编译预处理3
  • 展示数据可视化的魅力,如何通过图表、动画等形式让数据说话
  • 夜读丨一位医生0点后的朋友圈
  • 著名电化学家、我国工业电化学奠基人之一郭鹤桐逝世
  • 朱雨玲:从前世界第一到兼职运动员,30岁后开始“玩”乒乓
  • 马拉松夺冠机器人将小批量量产:价格与一台入门级小轿车差不多
  • 天工摘得全球首个人形机器人半马冠军:中国机器人产业正努力跑向人机共生社会
  • 希音、Temu告知美国消费者4月25日起涨价:关税变化导致运营成本上升