IPC通信--socket

1.windows环境

在C++中,Windows环境下实现socket通信的客户端与服务端的流程如下:

  1. 创建套接字:使用socket()函数创建一个套接字。
  2. 绑定套接字:使用bind()函数将套接字与一个地址(IP和端口)绑定在一起。
  3. 监听连接:使用listen()函数让服务器开始监听客户端的连接请求。
  4. 主动连接:使用connect()函数建立与指定IP地址和端口号的服务器的连接
  5. 接受连接:使用accept()函数接受客户端的连接请求。
  6. 发送和接收数据:使用send()和recv()函数进行数据的发送和接收。
  7. 关闭套接字:使用closesocket()函数关闭套接字。
  8. select函数:是一个用于I/O多路复用的函数。它可以同时监控多个socket,当某个socket上有数据可读、可写或者出现异常时,select()函数会返回。这样可以避免阻塞等待某个socket上的事件,提高程序的效率。

 socket()函数 

用于创建套接字的函数

#include <winsock2.h>SOCKET socket(int af, int type, int protocol);

参数说明:

  • af:地址族(Address Family),表示所使用的协议族。常用的值有AF_INET(IPv4协议)和AF_INET6(IPv6协议)。
  • type:套接字类型,表示套接字的功能。常用的值有SOCK_STREAM(面向连接的流式套接字,如TCP)和SOCK_DGRAM(无连接的数据报套接字,如UDP)。
  • protocol:协议类型,通常设置为0,让系统自动选择合适的协议。

返回值:

  • 如果成功,返回一个套接字描述符(非负整数)。
  • 如果失败,返回INVALID_SOCKET(-1)。

可能遇到的问题:

  1. 在使用socket()函数之前,需要先调用WSAStartup()函数初始化Winsock库。
  2. 在使用完套接字后,需要调用closesocket()函数关闭套接字。
  3. 在使用socket()函数时,可能会遇到错误,可以通过调用WSAGetLastError()函数获取错误代码。

 bind()函数

用于将套接字与特定的IP地址和端口号绑定。具体定义如下: 

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

参数说明:

  • sockfd:套接字描述符,由socket()函数创建。
  • addr:指向struct sockaddr结构体的指针,包含了要绑定的IP地址和端口号信息。
  • addrlen:addr指针所指向的结构体的大小。

返回值:

  • 成功:返回0。
  • 失败:返回-1,并设置errno为相应的错误码。

可能遇到的问题:

  1. 如果传入的sockfd不是有效的套接字描述符,bind()函数将返回-1,并设置errno为EBADF(Bad file number)。
  2. 如果传入的addr指针为NULL,bind()函数将返回-1,并设置errno为EINVAL(Invalid argument)。
  3. 如果传入的addrlen小于实际结构体大小,bind()函数将返回-1,并设置errno为EINVAL(Invalid argument)。
  4. 如果传入的IP地址和端口号已经被其他套接字绑定,bind()函数将返回-1,并设置errno为EADDRINUSE(Address already in use)。
  5. 如果传入的IP地址不在本地主机上,bind()函数将返回-1,并设置errno为EADDRNOTAVAIL(Cannot assign requested address)。

 listen()函数

listen()函数用于监听来自客户端的连接请求。它是TCP服务器端套接字的一个函数,用于设置套接字为监听模式,以便接受客户端的连接请求。

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

参数:

  • sockfd:一个已绑定到本地地址(使用bind()函数)的服务端套接字描述符。
  • backlog:允许挂起的最大连接数。通常设置为5或更大的值。

返回值:

  • 成功:返回0。
  • 失败:返回-1,并设置errno。

可能遇到的问题:

  1. 如果sockfd不是一个有效的套接字描述符,listen()函数将返回-1,并设置errno为EBADF。
  2. 如果sockfd未绑定到一个本地地址,listen()函数将返回-1,并设置errno为EINVAL。
  3. 如果backlog小于0,listen()函数将返回-1,并设置errno为EINVAL。
  4. 如果系统资源不足,listen()函数将返回-1,并设置errno为EAGAIN或ENOMEM。

connect()函数

#include <winsock2.h>int connect(SOCKET         s,const struct sockaddr *name,int            namelen
);

参数说明:

  • s:一个有效的套接字描述符,由socket()函数创建。
  • name:指向一个sockaddr结构的指针,该结构包含了要连接的服务器的地址信息。
  • namelen:name参数指向的结构的大小(以字节为单位)。

返回值:

  • 如果成功,返回0;如果失败,返回SOCKET_ERROR。可以使用WSAGetLastError()函数获取错误代码。

可能遇到的问题:

  1. 网络不可用或无法访问目标服务器。
  2. 目标服务器未运行或未监听指定的端口。
  3. 连接超时或被拒绝。
  4. 本地计算机上的防火墙设置阻止了连接。
  5. 本地计算机上的网络配置问题。

accept()函数

accept()函数用于接受一个已连接的客户端请求。它是在服务器端使用的,用于从已完成连接队列中取出一个连接请求,并创建一个新的套接字与客户端进行通信。

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>SOCKET accept(SOCKET   s,struct sockaddr *addr,int      *addrlen
);

参数说明:

  1. s:服务器端的套接字描述符,通常是通过socket()函数创建的。
  2. addr:指向一个sockaddr结构体的指针,用于存储客户端的地址信息。
  3. addrlen:指向一个整数的指针,表示addr缓冲区的大小。在调用accept()之前,需要将addrlen设置为addr缓冲区的大小;在调用accept()之后,addrlen将被设置为实际接收到的客户端地址信息的长度。

返回值:

  • 如果成功,accept()函数返回一个新的套接字描述符,用于与客户端进行通信。
  • 如果失败,返回INVALID_SOCKET(通常为-1)。

可能遇到的问题:

  1. 如果在调用accept()之前没有调用bind()和listen()函数,将无法接受客户端的连接请求。
  2. 如果客户端连接请求的数量超过了系统允许的最大值,accept()函数可能会阻塞,直到有可用的连接请求为止。
  3. 如果客户端连接请求被拒绝,accept()函数将返回错误代码。

 select()函数

#include <sys/select.h>
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

参数说明:

  • nfds:需要监控的文件描述符的最大值加1。
  • readfds:需要监控可读事件的socket文件描述符集合。
  • writefds:需要监控可写事件的socket文件描述符集合。
  • exceptfds:需要监控异常事件的socket文件描述符集合。
  • timeout:select()函数的超时时间,如果设置为NULL,则表示永远等待。

返回值:

  • 成功:返回就绪的文件描述符个数。
  • 超时:返回0。
  • 出错:返回-1。

可能遇到的问题:

  1. 每次调用select()函数时,都需要重新设置文件描述符集合,这可能会导致效率较低。
  2. select()函数只能处理最多1024个文件描述符,如果需要处理更多的文件描述符,可以使用poll()函数。
  3. select()函数在Windows环境下不可用,可以使用WSAEventSelect()函数替代。

示例

#include <stdio.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>#pragma comment(lib, "Ws2_32.lib")int main() {WSADATA wsaData;WSAStartup(MAKEWORD(2, 2), &wsaData);SOCKET listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);sockaddr_in serverAddr;serverAddr.sin_family = AF_INET;serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);serverAddr.sin_port = htons(8888);bind(listenSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr));listen(listenSocket, 5);fd_set readfds;FD_ZERO(&readfds);FD_SET(listenSocket, &readfds);while (1) {struct timeval timeout;timeout.tv_sec = 5;timeout.tv_usec = 0;int ret = select(0, &readfds, NULL, NULL, &timeout);if (ret == SOCKET_ERROR) {printf("select error: %d", WSAGetLastError());break;} else if (ret == 0) {printf("select timeout");continue;}for (int i = 0; i < listenSocket + 1; i++) {if (FD_ISSET(i, &readfds)) {if (i == listenSocket) {sockaddr_in clientAddr;int clientAddrLen = sizeof(clientAddr);SOCKET clientSocket = accept(listenSocket, (SOCKADDR*)&clientAddr, &clientAddrLen);FD_SET(clientSocket, &readfds);printf("new connection: %d", clientSocket);} else {char buffer[1024];int recvLen = recv(i, buffer, sizeof(buffer) - 1, 0);if (recvLen <= 0) {closesocket(i);FD_CLR(i, &readfds);printf("connection closed: %d", i);} else {buffer[recvLen] = '\0';printf("received from %d: %s", i, buffer);}}}}}closesocket(listenSocket);WSACleanup();return 0;
}

send()函数

send()函数用于发送数据

#include <sys/types.h>
#include <sys/socket.h>
ssize_t send(int sockfd, const void *buf, size_t len, int flags);

参数说明:

  • sockfd:表示要发送数据的套接字描述符。
  • buf:指向要发送数据的缓冲区。
  • len:要发送数据的长度。
  • flags:可选参数,用于设置发送数据的行为,如阻塞或非阻塞等。常用的标志有:MSG_DONTROUTE(不查找路由表)、MSG_OOB(发送带外数据)等。

返回值:

  • 成功时,返回实际发送的字节数。
  • 失败时,返回-1,并设置errno为相应的错误码。

可能遇到的问题:

  1. 发送缓冲区满:当发送缓冲区满时,send()函数会阻塞,直到有足够的空间可用。可以通过设置socket选项SO_SNDBUF来调整发送缓冲区的大小。
  2. 网络中断:当网络连接中断时,send()函数可能会返回-1,并设置errno为EINTR。此时,可以尝试重新发送数据。
  3. 地址不可达:当目标地址不可达时,send()函数会返回-1,并设置errno为EHOSTUNREACH。需要检查目标地址是否正确。
  4. 超时:当发送操作超时时,send()函数会返回-1,并设置errno为EAGAIN或EWOULDBLOCK。可以通过设置socket选项SO_SNDTIMEO来设置发送超时时间。

recv()函数

用于接收从指定的socket发送过来的数据

#include <winsock2.h>int recv( SOCKET s, char *buf,  int len,  int flags);

参数说明:

  • s:指定要接收数据的socket。
  • buf:指向接收到的数据的缓冲区。
  • len:指定要接收的最大字节数。
  • flags:通常设置为0,表示使用默认操作。

返回值:

  • 如果成功,返回接收到的字节数;
  • 如果失败,返回SOCKET_ERROR,可以通过调用WSAGetLastError()函数获取错误代码。

可能遇到的问题:

  1. 网络连接断开或对方关闭连接,recv()函数会返回0,表示连接已关闭。
  2. 阻塞模式下,如果没有数据可接收,recv()函数会一直等待,直到有数据到达或发生错误。
  3. 非阻塞模式下,如果没有数据可接收,recv()函数会立即返回SOCKET_ERROR,错误代码为WSAEWOULDBLOCK。
  4. 缓冲区大小不足以容纳接收到的数据,recv()函数会截断数据并返回实际接收到的字节数。
  5. 网络延迟或丢包可能导致数据接收不完整或顺序错乱。

代码示例

服务端

#include <iostream>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib") // Winsock Library#define BUF_SIZE 100
#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 1234
int main() {WSADATA wsaData;SOCKET hServSock, hClntSock;char buffer[BUF_SIZE];int strLen;SOCKADDR_IN servAddr, clntAddr;int clntAddrSize;// 初始化Winsockif (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {std::cerr << "WSAStartup failed.\n";return -1;}// 创建套接字hServSock = socket(AF_INET, SOCK_STREAM, 0);if (hServSock == INVALID_SOCKET) {std::cerr << "Socket creation failed.\n";return -1;}// 绑定套接字memset(&servAddr, 0, sizeof(servAddr));servAddr.sin_family = AF_INET;servAddr.sin_addr.s_addr = inet_addr(SERVER_IP);servAddr.sin_port = htons(SERVER_PORT);if (bind(hServSock, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR) {std::cerr << "Bind failed.\n";return -1;}// 监听套接字if (listen(hServSock, 5) == SOCKET_ERROR) {std::cerr << "Listen failed.\n";return -1;}// 接受客户端的连接请求clntAddrSize = sizeof(clntAddr);hClntSock = accept(hServSock, (SOCKADDR*)&clntAddr, &clntAddrSize);if (hClntSock == INVALID_SOCKET) {std::cerr << "Accept failed.\n";return -1;}// 接收并打印数据while ((strLen = recv(hClntSock, buffer, BUF_SIZE, 0)) != 0) {buffer[strLen] = '\0';std::cout << "Received: " << buffer << std::endl;}// 关闭套接字closesocket(hClntSock);closesocket(hServSock);WSACleanup();return 0;
}

客户端

 

#include <iostream>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib") // Winsock Library#define BUF_SIZE 100
#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 1234
int main() {WSADATA wsaData;SOCKET hSocket;char buffer[BUF_SIZE];int strLen;SOCKADDR_IN servAddr;// 初始化Winsockif (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {std::cerr << "WSAStartup failed.\n";return -1;}// 创建套接字hSocket = socket(PF_INET, SOCK_STREAM, 0);if (hSocket == INVALID_SOCKET) {std::cerr << "Socket creation failed.\n";return -1;}// 设置服务器地址结构体memset(&servAddr, 0, sizeof(servAddr));servAddr.sin_family = AF_INET;servAddr.sin_addr.s_addr = inet_addr(SERVER_IP);servAddr.sin_port = htons(SERVER_PORT);// 连接到服务器if (connect(hSocket, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR) {std::cerr << "Connect failed.\n";return -1;}// 发送数据while (true) {std::cin >> buffer;send(hSocket, buffer, strlen(buffer), 0);}// 关闭套接字closesocket(hSocket);WSACleanup();return 0;
}

编译

g++ server.cpp -o server -lws2_32

g++ client.cpp -o client -lws2_32

2.Linux环境

 在C语言的Linux环境下,实现socket通信以实现进程间通信,可以分为以下几个步骤:

  1. 创建socket
  2. 绑定地址和端口
  3. 监听连接
  4. 发送和接收数据

 创建socket

 需要包含头文件<sys/types.h><sys/socket.h><netinet/in.h>。然后,使用socket()函数创建一个socket

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>int main() {int server_sockfd;server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
}

 绑定地址和端口

使用bind()函数将socket与指定的地址和端口绑定

#include <arpa/inet.h>struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8888);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");bind(server_sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));

监听连接/主动连接

使用listen()函数开始监听客户端的连接请求

listen(server_sockfd, 5);

使用connect()函数用于建立与指定IP地址和端口号的服务器之间的连接 

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

参数说明:

  • sockfd:套接字描述符,由socket()函数创建。
  • addr:指向目标服务器的地址结构体指针,通常使用struct sockaddr_in来表示IPv4地址。
  • addrlen:地址结构体的大小,对于struct sockaddr_in,其大小为sizeof(struct sockaddr_in)

返回值:

  • 成功:返回0,表示连接已建立。
  • 失败:返回-1,表示连接失败,可以通过errno获取错误码。

发送和接收数据

服务端使用accept()函数接受客户端的连接请求,然后使用send()recv()函数进行数据的发送和接收。

#include <unistd.h>struct sockaddr_in client_addr;
socklen_t client_addr_len = sizeof(client_addr);
int client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_addr, &client_addr_len);char buffer[1024];
send(client_sockfd, "Hello, client!", strlen("Hello, client!"), 0);
recv(client_sockfd, buffer, sizeof(buffer), 0);

代码示例

服务端

#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>int main() {// 创建socketint server_fd = socket(AF_INET, SOCK_STREAM, 0);// 定义sockaddr_in结构体struct sockaddr_in server_addr;memset(&server_addr, 0, sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_port = htons(8888); // 端口号server_addr.sin_addr.s_addr = htonl(INADDR_ANY); // IP地址// 绑定socketbind(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr));// 监听socketlisten(server_fd, 5);// 接受客户端连接struct sockaddr_in client_addr;socklen_t client_addr_len = sizeof(client_addr);int client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &client_addr_len);// 向客户端发送数据char msg[] = "Hello, client!";send(client_fd, msg, strlen(msg), 0);// 关闭socketclose(client_fd);close(server_fd);return 0;
}

客户端

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>int main() {// 创建socketint client_fd = socket(AF_INET, SOCK_STREAM, 0);// 定义sockaddr_in结构体struct sockaddr_in server_addr;memset(&server_addr, 0, sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_port = htons(8888); // 端口号server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // IP地址// 连接服务器connect(client_fd, (struct sockaddr*)&server_addr, sizeof(server_addr));// 接收服务器发送的数据char buffer[1024] = {0};recv(client_fd, buffer, sizeof(buffer), 0);printf("Received from server: %s\n", buffer);// 关闭socketclose(client_fd);return 0;
}

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

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

相关文章

基于Gabor滤波器的指纹图像识别,Matlab实现

博主简介&#xff1a; 专注、专一于Matlab图像处理学习、交流&#xff0c;matlab图像代码代做/项目合作可以联系&#xff08;QQ:3249726188&#xff09; 个人主页&#xff1a;Matlab_ImagePro-CSDN博客 原则&#xff1a;代码均由本人编写完成&#xff0c;非中介&#xff0c;提供…

2024年【山东省安全员C证】考试试卷及山东省安全员C证复审模拟考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 山东省安全员C证考试试卷是安全生产模拟考试一点通生成的&#xff0c;山东省安全员C证证模拟考试题库是根据山东省安全员C证最新版教材汇编出山东省安全员C证仿真模拟考试。2024年【山东省安全员C证】考试试卷及山东省…

一个线程可以有几个Handler,几个Looper,几个MessageQueue对象?

一个线程可以有多个Handler&#xff0c;但是只有一个Looper对象,只有一个MessageQueue对象。 在Looper的prepare方法中创建了Looper对象&#xff0c;并放入到ThreadLocal中&#xff0c;并通过ThreadLocal来获取looper的对象, ThreadLocal的内部维护了一个ThreadLocalMap类, 里…

【Linux】信号的处理{信号处理的时机/了解寄存器/内核态与用户态/信号操作函数}

文章目录 0.对于信号捕捉的理解1.信号处理的时机1.1 何时处理信号&#xff1f;1.2 内核态和用户态1.3 内核态和用户态的切换 2.了解寄存器3.信号捕捉的原理4.信号操作函数4.1sighandler_t signal(int signum, sighandler_t handler);4.2int sigaction(int signum, const struct…

express+mysql+vue,从零搭建一个商城管理系统15--快递查询(对接快递100)

提示&#xff1a;学习express&#xff0c;搭建管理系统 文章目录 前言一、安装md5&#xff0c;axios二、新建config/logistics.js三、修改routes/order.js四、查询物流信息五、试错与误区总结 前言 需求&#xff1a;主要学习express&#xff0c;所以先写service部分 快递100API…

工业项目中你连DCS系统都没见过?

什么是DCS DCS&#xff0c;即分散控制系统&#xff0c;是一种用于监控和控制工业过程的系统。它通过连接多个控制器、传感器和执行器实现自动化控制&#xff0c;提高生产效率和安全性。在中国&#xff0c;随着工业化和自动化水平的提高&#xff0c;DCS技术得到了广泛应用和快速…

创建Message对象的方式及区别?Message.obtain()怎么维护消息池 ?Handler 有哪些发送消息的方法?

Message对象创建的方式有哪些&#xff0c; 区别&#xff1f; 直接new一个obtain&#xff08;&#xff09;方法获取handler.obtainMessage()方法获取。 下面两个方式是从对象池中获取&#xff0c;可以避免message对象重复的创建。 Message.obtain()怎么维护消息池的Handler &…

外包干了10天,技术倒退明显

先说情况&#xff0c;大专毕业&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近6年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试&#xf…

推免保研夏令营/预推免面试记录—北大软微

0x00简述 0x01 面试经历 0x02 相关资料下载 0x00简述 0x01 面试经历 0x02 相关资料下载 挖坑待写

SpringMVC 简介及入门级的快速搭建详细步骤

MVC 回顾 MVC&#xff0c;即Model-View-Controller&#xff08;模型-视图-控制器&#xff09;设计模式&#xff0c;是一种广泛应用于软件工程中&#xff0c;特别是Web应用开发中的架构模式。它将应用程序分为三个核心组件&#xff1a; Model&#xff08;模型&#xff09;&#…

面试问答示范

文章目录 请做个自我介绍您的学历是统招吗&#xff1f;可以在学信网查询吗是全日制吗是双证吗&#xff1f;请介绍一下你上家公司的情况。介绍一下你们公司的服务器架构&#xff08;网络架构&#xff09;。说说你在工作中处理过的最棘手的技术问题讲一讲上家公司做过的项目为什么…

网络安全作业4

title: 文件上传/文件包含漏洞学习 date: 2016-04-25 21:52:19 categories: 安全 tags: Web安全 ** 文件上传漏洞 ** 在Web程序中&#xff0c;经常需要用到文件上传的功能。如用户或者管理员上传图片&#xff0c;或者其它文件。如果没有限制上传类型或者限制不严格被绕过&…

代码随想录笔记|C++数据结构与算法学习笔记-哈希表(一)|有效的字母异位词、两个数组的交集、快乐数、两数之和、四数相加II

文章目录 242.有效的字母异位词哈希法解法解题思路伪代码c代码 349.两个数组的交集set解决伪代码c代码 数组解决 202.快乐数思路伪代码讲解C代码 1.两数之和思路map解题过程伪代码C代码 454.四数相加II整体思路map解题过程注意事项伪代码C代码 《代码随想录链接》 本文基于代码…

PagePlug多条件查询方案

正确实现 使用Case When来编写查询条件 SELECT * FROM pc_ticket_tax_cloud WHERE 11 AND (CASE WHEN {{data_table.searchText ! }} THEN xsddm like {{data_table.searchText || ""}}%ELSE 11 END ) AND (CASE WHEN {{doc_code_input.text ! }} THEN doc_code li…

【C语言算法】求逆序对数目(C语言+归并排序)

题目描述 Background Raymond Babbitt drives his brother Charlie mad. Recently Raymond counted 246 toothpicks spilled all over the floor in an instant just by glancing at them. And he can even count Poker cards. Charlie would love to be able to do cool thin…

代码随想录Day31

Day 31 贪心算法 Part01 今日任务 455.分发饼干 摆动序列 最大子序和 代码实现 455.分发饼干 //自己想的&#xff0c;虽然看着不让代码随想录给出的解法简洁&#xff0c;但是理论是一样的public int findContentChildren(int[] g, int[] s) {Arrays.sort(g);Arrays.sort(…

Git浅谈配置文件和免密登录

一、文章内容 简述git三种配置ssh免密登录以及遇见的问题git可忽略文件git remote 相关操作 二、Git三种配置 项目配置文件(局部)&#xff1a;项目路径/.git/config 文件 git config --local user.name name git config --local user.email 123qq.cc全局配置文(所有用户): …

【Web】记录CISCN 2021 总决赛 ezj4va题目复现——AspectJWeaver

目录 前言 原理分析 step 0 step 1 EXP 前文&#xff1a;【Web】浅聊Java反序列化之AspectJWeaver——任意文件写入-CSDN博客 前言 这就是当年传说中的零解题嘛&#x1f62d;&#xff0c;快做&#x1f92e;了 有了之前的经验&#xff0c;思路顺挺快的&#xff0c;中间不…

网络基础(一)初识

1、计算机网络背景 1.1、网络发展 1. 独立模式: 计算机之间相互独立&#xff1b; 2. 网络互联: 多台计算机连接在一起&#xff0c;完成数据共享&#xff1b; 3. 局域网LAN: 计算机数量更多了, 通过交换机和路由器连接在一起; 4. 广域网WAN: 将远隔千里的计算机都连在一起;…

突破编程_C++_STL教程( priority_queue 的基础知识)

1 std::priority_queue 概述 std::priority_queue 是 C 标准库中的一个容器适配器&#xff0c;它提供了一种实现优先队列数据结构的机制。优先队列是一种特殊的队列&#xff0c;其中元素的出队顺序不是基于它们进入队列的顺序&#xff0c;而是基于它们的优先级。优先级最高的元…