【window环境、Linux环境、QT三种方法实现TCP通信】

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、Windows环境下实现TCP通信
    • 1.服务器
    • 2.客户端
    • 3.运行
  • 二、Linux环境下实现TCP通信
    • 1.服务端
    • 2.客户端
  • 三、Qt实现TCP通信
    • 1.服务端
    • 1.客户端
  • 总结


前言

大多数项目都在Linux系列的操作系统下开发服务器端,而多数客户端是在Windows平台下开发的。不仅如此,有时应用程序还需要在两个平台之间相互切换。因此,学习套接字编程的过程中,有必要兼顾Windows和Linux两大平台。另外,这两大平台下的套接字编程非常类似,如果把其中相似的部分放在一起讲解,将大大提高学习效率。只要理解好其中一个平台下的网络编程方法,就很容易通过分析差异掌握另一平台。因为不论什么方式实现,底层的逻辑都是完全一致的。


一、Windows环境下实现TCP通信

为了在Winsock基础上开发网络程序,需要做如下准备,以下两个文件都是系统自带的,包含时注意目标平台版本与库的版本一致。
导入头文件winsock2.h。
链接ws2_32.lib库(库名称和链接目录)。

1.服务器

#include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h>void ErrorHandling(char *message){fputs(message, stderr);fputs("\n", stderr);exit(1);
}int main(int argc, char * argv[]){WSADATA wsaData;SOCKET hServSock, hClntSock;SOCKADDR_IN servAddr, clntAddr;int szClntAddr;char message[] = "Hello World!";if (argc != 2) {printf("Usage : %s <port>", argv[0]);exit(1);}if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)ErrorHandling("WSAStartup() error!");hServSock = socket(PF_INET, SOCK_STREAM, 0);if (hServSock == INVALID_SOCKET)ErrorHandling("socket() error!");memset(&servAddr, 0, sizeof(servAddr));servAddr.sin_family = AF_INET;servAddr.sin_addr.s_addr = htonl(INADDR_ANY);servAddr.sin_port = htons(atoi(argv[1]));if (bind(hServSock, (SOCKADDR *)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)ErrorHandling("bind() error!");if (listen(hServSock, 5) == SOCKET_ERROR)ErrorHandling("listen() error!");szClntAddr = sizeof(clntAddr);hClntSock = accept(hServSock, (SOCKADDR*)&clntAddr, &szClntAddr);if (hClntSock == INVALID_SOCKET)ErrorHandling("accept() error!");fputs("sending message...", stderr);fputs("", stderr);send(hClntSock, message, sizeof(message), 0);closesocket(hClntSock);closesocket(hServSock);WSACleanup();return 0;
}

2.客户端

#include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h>
void ErrorHandling(char* message);int main(int argc, char *argv[]) 
{WSADATA wsaData;SOCKET hSocket;SOCKADDR_IN servAddr;char message[30];int strlen;if (argc != 3) {printf("Usage: %s <IP> <port>", argv[0]);exit(1);}if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)ErrorHandling("WSAStartup() error!");hSocket = socket(PF_INET, SOCK_STREAM, 0);if (hSocket == INVALID_SOCKET)ErrorHandling("socket() error!");memset(&servAddr, 0, sizeof(servAddr));servAddr.sin_family = AF_INET;servAddr.sin_addr.s_addr = inet_addr(argv[1]);servAddr.sin_port = htons(atoi(argv[2]));if (connect(hSocket, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)ErrorHandling("connect() error!");strlen = recv(hSocket, message, sizeof(message) - 1, 0);if (strlen == -1)ErrorHandling("read() error!");printf("Message from server:%s", message);closesocket(hSocket);WSACleanup();return 0;
}void ErrorHandling(char * message) {fputs(message, stderr);fputc('\n', stderr);exit(1);
}

3.运行

运行时直接进入到可执行程序文件,使用命令行运行

C:\tcpip>tcp_win_server 9190
C:\tcpip>tcp_win_client 127.0.0.1 9190

二、Linux环境下实现TCP通信

1.服务端

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
void error_handling(char *message);
int main(int argc,char *argv[])
{int serv sock;int clnt sock;struct sockaddr in serv addr;struct sockaddr in clnt addr;socklen t clnt addr size;char message[]="Hello World!";if(argc!=2){printf("Usage :%s<port>\n",argv[0]);exit(1);}serv sock=Socket(PF INET,SOCK STREAM,0);if(serv sock ==-1)error_handling("socket() error");memset(&serv_addr,0,sizeof(serv addr));serv_addr.sin_family=AF INET;serv_addr.sin_addr.s addr=htonl(INADDR ANY);serv_addr.sin_port=htons(atoi(argv[1]));if(bind(serv_sock,(struct sockaddr*)&serv_addr, sizeof(serv_addr))==-1)error_handling("bind() error");if(listen(serv sock,5)==-1)error_handling("listen() error");clnt addr size=sizeof(clnt addr);cInt sock=accept(sery sock,(struct sockaddr*)&cInt addr,&cInt addr size);if(clnt sock==-1)error_handling("accept() error");write(clnt_sock,message,sizeof(message));close(clnt sock);close(serv sock);return 0;
}
void error handling(char *message)
{fputs(message, stderr);fputc('\n',stderr);exit(1);
}

2.客户端

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
void error handling(char *message);
int main(int argc, char* argv[])
{int sock;struct sockaddr_in serv_addr;char message[30];int str_len;if(argc!-3){printf("Usage :%s<IP><port>\n",argv[0]);exit(1);}sock=socket(PF INET,SOCK STREAM, 0);if(sock == -1)error_handling("socket() error")memset(&serv addr,0,sizeof(serv addr));serv addr.sin family=AF INET;serv addr.sin addr.s addr-inet addr(argv[1]);serv_addr.sin port=htons(atoi(argv[2]));if(connect(sock,(struct sockaddr*)&serv addr,sizeof(serv_addr))==-1)error_handling("connect() error!");str len=read(sock,message,sizeof(message)-1);if(str len=--1)error_handling("read()error!");printf("Message from server :Xs n",message);close(sock);return 0;
}
void error handling(char*message)
{fputs(message, stderr)fputc('\n',stderr);exit(1);
}

三、Qt实现TCP通信

相对于前边两种方法,QT进行了一定封装,使用起来更加简洁。
在这里插入图片描述

1.服务端

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include  <QtNetwork>
#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")
#endifQString MainWindow::getLocalIP()
{//获取本机IPv4地址//! 本地主机名, QHostInfo 的静态函数 localHostName()可获取本机的主机名QString hostName = QHostInfo::localHostName();//! 返回指定的主机名的IP地址QHostInfo hostInfo = QHostInfo::fromName(hostName);QString localIP = "";//! 返回与 hostName()主机关联的IP地址列表QList<QHostAddress> addList = hostInfo.addresses();//for (int i = 0; i < addList.count(); i++){QHostAddress aHost = addList.at(i);if (QAbstractSocket::IPv4Protocol == aHost.protocol()){//192.168.23.114localIP=aHost.toString();break;}}return localIP;
}void MainWindow::closeEvent(QCloseEvent *event)
{//关闭窗口时停止监听if (tcpServer->isListening())tcpServer->close();;//停止网络监听event->accept();
}MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);LabListen=new QLabel("监听状态:");LabListen->setMinimumWidth(150);ui->statusBar->addWidget(LabListen);LabSocketState=new QLabel("Socket状态:");//LabSocketState->setMinimumWidth(200);ui->statusBar->addWidget(LabSocketState);//本机IPQString localIP = getLocalIP();this->setWindowTitle(this->windowTitle()+"----本机IP:"+localIP);ui->comboIP->addItem(localIP);//! tcp服务端tcpServer = new QTcpServer(this);//! 如果有新的连接connect(tcpServer, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
}MainWindow::~MainWindow()
{delete ui;
}//! 服务端有新的连接时
void MainWindow::onNewConnection()
{
//    ui->plainTextEdit->appendPlainText("有新连接");//! 创建socket,返回下一个等待接入的连接tcpSocket = tcpServer->nextPendingConnection();//! connectToHost()成功连接到服务器后发射此信号,连接成功后显示connect(tcpSocket, SIGNAL(connected()), this, SLOT(onClientConnected()));//! 客户端接入时onClientConnected();//! 当socket断开连接后发射此信号connect(tcpSocket, SIGNAL(disconnected()), this, SLOT(onClientDisconnected()));//! 当socket的状态变化时发射此信号,参数socketState表示了socket当前的状态connect(tcpSocket,SIGNAL(stateChanged(QAbstractSocket::SocketState)), this,SLOT(onSocketStateChange(QAbstractSocket::SocketState)));onSocketStateChange(tcpSocket->state());//! 当缓冲区有新数据需要读取时发射此信号,在此信号的槽函数里读取缓冲区的数据connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(onSocketReadyRead()));
}//socket状态变化时
void MainWindow::onSocketStateChange(QAbstractSocket::SocketState socketState)
{switch(socketState){case QAbstractSocket::UnconnectedState:LabSocketState->setText("scoket状态:UnconnectedState");break;case QAbstractSocket::HostLookupState:LabSocketState->setText("scoket状态:HostLookupState");break;case QAbstractSocket::ConnectingState:LabSocketState->setText("scoket状态:ConnectingState");break;case QAbstractSocket::ConnectedState:LabSocketState->setText("scoket状态:ConnectedState");break;case QAbstractSocket::BoundState:LabSocketState->setText("scoket状态:BoundState");break;case QAbstractSocket::ClosingState:LabSocketState->setText("scoket状态:ClosingState");break;case QAbstractSocket::ListeningState:LabSocketState->setText("scoket状态:ListeningState");}
}//客户端接入时
void MainWindow::onClientConnected()
{ui->plainTextEdit->appendPlainText("**client socket connected");ui->plainTextEdit->appendPlainText("**peer name:" + tcpSocket->peerName());//! 在已连接状态下,返回对方socket的地址ui->plainTextEdit->appendPlainText("**peer address:" + tcpSocket->peerAddress().toString());ui->plainTextEdit->appendPlainText("**peer port:" + QString::number(tcpSocket->peerPort()));
}void MainWindow::onClientDisconnected()
{//客户端断开连接时ui->plainTextEdit->appendPlainText("**client socket disconnected");tcpSocket->deleteLater();//    deleteLater();//QObject::deleteLater();
}void MainWindow::onSocketReadyRead()
{//读取缓冲区行文本
//    QStringList   lines;while(tcpSocket->canReadLine())ui->plainTextEdit->appendPlainText("[in] " + tcpSocket->readLine());
//        lines.append(clientConnection->readLine());
}//开始监听
void MainWindow::on_actStart_triggered()
{//! IP地址QString IP = ui->comboIP->currentText();//! 端口quint16 port = ui->spinPort->value();QHostAddress addr(IP);tcpServer->listen(addr, port);//
//    tcpServer->listen(QHostAddress::LocalHost,port);// Equivalent to QHostAddress("127.0.0.1").ui->plainTextEdit->appendPlainText("**开始监听...");ui->plainTextEdit->appendPlainText("**服务器地址:" + tcpServer->serverAddress().toString());ui->plainTextEdit->appendPlainText("**服务器端口:" + QString::number(tcpServer->serverPort()));ui->actStart->setEnabled(false);ui->actStop->setEnabled(true);LabListen->setText("监听状态:正在监听");
}void MainWindow::on_actStop_triggered()
{//停止监听if (tcpServer->isListening()) //tcpServer正在监听{tcpServer->close();//停止监听ui->actStart->setEnabled(true);ui->actStop->setEnabled(false);LabListen->setText("监听状态:已停止监听");}
}void MainWindow::on_actClear_triggered()
{ui->plainTextEdit->clear();
}void MainWindow::on_btnSend_clicked()
{//发送一行字符串,以换行符结束QString  msg=ui->editMsg->text();ui->plainTextEdit->appendPlainText("[out] "+msg);ui->editMsg->clear();ui->editMsg->setFocus();QByteArray  str=msg.toUtf8();str.append('\n');//添加一个换行符tcpSocket->write(str);
}void MainWindow::on_actHostInfo_triggered()
{//获取本机地址QString hostName=QHostInfo::localHostName();//本地主机名ui->plainTextEdit->appendPlainText("本机主机名:"+hostName+"\n");QHostInfo   hostInfo=QHostInfo::fromName(hostName);QList<QHostAddress> addList=hostInfo.addresses();//if (!addList.isEmpty())for (int i=0;i<addList.count();i++){QHostAddress aHost=addList.at(i);if (QAbstractSocket::IPv4Protocol==aHost.protocol()){QString IP=aHost.toString();ui->plainTextEdit->appendPlainText("本机IP地址:"+aHost.toString());if (ui->comboIP->findText(IP)<0)ui->comboIP->addItem(IP);}}}mainwindow.h```cpp
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include    <QTcpServer>
#include    <QLabel>namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECT
private:QLabel  *LabListen;//状态栏标签QLabel  *LabSocketState;//状态栏标签QTcpServer *tcpServer; //TCP服务器QTcpSocket *tcpSocket;//TCP通讯的SocketQString getLocalIP();//获取本机IP地址
protected:void   closeEvent(QCloseEvent *event);
public:explicit MainWindow(QWidget *parent = 0);~MainWindow();
private slots:
//自定义槽函数void    onNewConnection();//QTcpServer的newConnection()信号void    onSocketStateChange(QAbstractSocket::SocketState socketState);void    onClientConnected(); //Client Socket connectedvoid    onClientDisconnected();//Client Socket disconnectedvoid    onSocketReadyRead();//读取socket传入的数据
//UI生成的void on_actStart_triggered();void on_actStop_triggered();void on_actClear_triggered();void on_btnSend_clicked();void on_actHostInfo_triggered();
private:Ui::MainWindow *ui;
};#endif // MAINWINDOW_H

1.客户端

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include  <QHostAddress>
#include  <QHostInfo>
#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")
#endif
QString MainWindow::getLocalIP()
{QString hostName = QHostInfo::localHostName();//本地主机名QHostInfo hostInfo = QHostInfo::fromName(hostName);QString localIP = "";QList<QHostAddress> addList = hostInfo.addresses();//for (int i = 0; i < addList.count(); i++){QHostAddress aHost = addList.at(i);if (QAbstractSocket::IPv4Protocol == aHost.protocol()){localIP=aHost.toString();break;}}return localIP;
}
void MainWindow::closeEvent(QCloseEvent *event)
{if (tcpClient->state()==QAbstractSocket::ConnectedState)tcpClient->disconnectFromHost();event->accept();
}MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);tcpClient = new QTcpSocket(this); //创建socket变量LabSocketState=new QLabel("Socket状态:");//状态栏标签LabSocketState->setMinimumWidth(250);ui->statusBar->addWidget(LabSocketState);//本机IPQString localIP = getLocalIP();this->setWindowTitle(this->windowTitle() + "----本机IP:" + localIP);ui->comboServer->addItem(localIP);connect(tcpClient,SIGNAL(connected()),this,SLOT(onConnected()));connect(tcpClient,SIGNAL(disconnected()),this,SLOT(onDisconnected()));connect(tcpClient,SIGNAL(stateChanged(QAbstractSocket::SocketState)),this,SLOT(onSocketStateChange(QAbstractSocket::SocketState)));connect(tcpClient,SIGNAL(readyRead()),this,SLOT(onSocketReadyRead()));
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::onConnected()
{ //connected()信号槽函数ui->plainTextEdit->appendPlainText("**已连接到服务器");ui->plainTextEdit->appendPlainText("**peer address:" + tcpClient->peerAddress().toString());ui->plainTextEdit->appendPlainText("**peer port:" + QString::number(tcpClient->peerPort()));ui->actConnect->setEnabled(false);ui->actDisconnect->setEnabled(true);
}void MainWindow::onDisconnected()
{//disConnected()信号槽函数ui->plainTextEdit->appendPlainText("**已断开与服务器的连接");ui->actConnect->setEnabled(true);ui->actDisconnect->setEnabled(false);
}void MainWindow::onSocketReadyRead()
{//readyRead()信号槽函数while(tcpClient->canReadLine())ui->plainTextEdit->appendPlainText("[in] "+tcpClient->readLine());
}void MainWindow::onSocketStateChange(QAbstractSocket::SocketState socketState)
{//stateChange()信号槽函数switch(socketState){case QAbstractSocket::UnconnectedState:LabSocketState->setText("scoket状态:UnconnectedState");break;case QAbstractSocket::HostLookupState:LabSocketState->setText("scoket状态:HostLookupState");break;case QAbstractSocket::ConnectingState:LabSocketState->setText("scoket状态:ConnectingState");break;case QAbstractSocket::ConnectedState:LabSocketState->setText("scoket状态:ConnectedState");break;case QAbstractSocket::BoundState:LabSocketState->setText("scoket状态:BoundState");break;case QAbstractSocket::ClosingState:LabSocketState->setText("scoket状态:ClosingState");break;case QAbstractSocket::ListeningState:LabSocketState->setText("scoket状态:ListeningState");}
}void MainWindow::on_actConnect_triggered()
{//连接到服务器QString     addr=ui->comboServer->currentText();quint16     port=ui->spinPort->value();tcpClient->connectToHost(addr,port);
//    tcpClient->connectToHost(QHostAddress::LocalHost,port);
}void MainWindow::on_actDisconnect_triggered()
{//断开与服务器的连接if (tcpClient->state()==QAbstractSocket::ConnectedState)tcpClient->disconnectFromHost();
}void MainWindow::on_actClear_triggered()
{ui->plainTextEdit->clear();
}void MainWindow::on_btnSend_clicked()
{//发送数据QString  msg=ui->editMsg->text();ui->plainTextEdit->appendPlainText("[out] "+msg);ui->editMsg->clear();ui->editMsg->setFocus();QByteArray str = msg.toUtf8();str.append('\n');tcpClient->write(str);
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include    <QTcpSocket>
#include    <QLabel>namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECT
private:QTcpSocket  *tcpClient;  //socketQLabel  *LabSocketState;  //状态栏显示标签QString getLocalIP();//获取本机IP地址
protected:void    closeEvent(QCloseEvent *event);
public:explicit MainWindow(QWidget *parent = 0);~MainWindow();private slots:
//自定义槽函数void    onConnected();void    onDisconnected();void    onSocketStateChange(QAbstractSocket::SocketState socketState);void    onSocketReadyRead();//读取socket传入的数据
//void on_actConnect_triggered();void on_actDisconnect_triggered();void on_actClear_triggered();void on_btnSend_clicked();private:Ui::MainWindow *ui;
};#endif // MAINWINDOW_H

总结

以上就是今天要讲的内容,本文整理了三种实现TCP通信的方法,从上层到偏底层,对于新手理解通信原理有极大帮助。

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

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

相关文章

告别SQL注入攻击之扰!揭秘强大防护策略,筑牢网站安全防线,畅享无忧体验!

SQL注入攻击是一种极具破坏性的Web漏洞&#xff0c;它利用应用程序对用户输入的处理不当&#xff0c;让恶意用户能够执行非授权的SQL查询&#xff0c;进而对数据库造成巨大损害。这种攻击方式可能导致数据泄露、系统崩溃等严重后果&#xff0c;因此必须引起高度重视。 为了有效…

语义分割模型——浅谈U-net相关理论

目录 1 U-net简介 1.1 U-net是什么 1.2 U-net的创新点及优势 2 U-net改进思路 2.1 编码器优化 2.2 跳跃连接优化 2.3 解码器优化 2.4 其他优化方式 2.5 注意事项 1 U-net简介 1.1 U-net是什么 Ronneberger等人于2015年基于FCN&#xff08;全卷积神经网络&#xff09…

预测房屋价格(使用SGDRegressor随机梯度下降回归)

线性回归&#xff1a;预测未来趋势01&#xff08;预测房屋价格&#xff09; 文章目录 线性回归&#xff1a;预测未来趋势01&#xff08;预测房屋价格&#xff09;前言一、案例介绍&#xff1a;二、架构图&#xff1a;&#xff08;流程图&#xff09;三、使用了什么技术&#xf…

代码随想录:二叉树18(Java)

目录 105.从前序与中序遍历序列构造二叉树 题目 代码 106.从中序与后序遍历序列构造二叉树 题目 代码 105.从前序与中序遍历序列构造二叉树 题目 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的…

利用Django中的缓存系统提升Web应用性能

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 在构建现代Web应用时&#xff0c;性能通常是至关重要的考虑因素之一。为了提高用户体验和应…

设计模式(六):原型模式

设计模式&#xff08;六&#xff09;&#xff1a;原型模式 1. 原型模式的介绍2. 原型模式的类图3. 原型模式的实现3.1 创建一个原型接口3.2 创建具体原型3.3 创建一个数据缓存类3.4 测试 1. 原型模式的介绍 原型模式&#xff08;Prototype Pattern&#xff09;属于创建型模式&…

人工智能(AI)与地理信息技术(GIS)的融合:开启智能地理信息时代

随着科技的不断发展&#xff0c;人工智能&#xff08;AI&#xff09;和地理信息技术&#xff08;GIS&#xff09;的应用越来越广泛&#xff0c;两者的结合更是为许多行业带来了前所未有的变革。本文将以“人工智能&#xff08;AI&#xff09;地理信息技术&#xff08;GIS&#…

【八股】Spring篇

why Spring? 1.使用它的IOC功能&#xff0c;在解耦上达到了配置级别。 2.使用它对数据库访问事务相关的封装。 3.各种其他组件与Spring的融合&#xff0c;在Spring中更加方便快捷的继承其他一些组件。 IoC和DI &#x1f449;IOC是Inversion of Control的缩写&#xff0c;“…

德语口语学习的8种练习方法

简洁明了一点&#xff0c;方便大家理解&#xff0c;我总结了以下8点&#xff1a; 1.模拟对话&#xff1a; 创造实际生活场景&#xff0c;例如购物、问路、餐厅点餐等&#xff0c;并自言自语或者与伙伴一起模拟这些对话。 参加角色扮演活动&#xff0c;通过不同情境练习口语。…

文末送资料|跟着开源学技术-ChatGPT开源项目-chatgpt-java

目录 功能特性 最简使用 进阶使用 函数调用&#xff08;Function Call&#xff09; 流式使用 流式配合Spring SseEmitter使用 多KEY自动轮询 大家好&#xff0c;我是充电君 今天带着大家来看个Java版本的ChatGPT。这个开源项目就是chatgpt-java。 Github&#xff1a; h…

Django与mysqlclient链接不成功

先检查自己的python是什么版本&#xff0c;是64位还是32位&#xff0c;这个自己去网上查。 我的是32位的&#xff0c;因为直接pip下载不了&#xff0c;网上也没有32位的whl&#xff0c;所以卸载重装一个64位的3.9.6的python 网上直接搜mysqlclient&#xff0c;找到对应py39也…

Excel vlookup函数的使用教程 和 可能遇到的错误解决方法

使用VLOOKUP示例 被查询的表格 表一 A列B列C列A1aB2bC3c 要匹配的列 表二 F列G列H列ACBDA 要G列匹配字母&#xff0c;H列匹配数字 G 使用公式VLOOKUP(F5,A:D,3,0) 参数说明 F5 是表二 F列第五行的A A:D表是要匹配的数据列表在A到D列&#xff0c;就是表一 &#xff08;注意…

什么样的汽车制造供应商管理平台 可以既高效又安全?

汽车制造供应商管理是汽车制造商最基础的工作项&#xff0c;因为在汽车制造环节&#xff0c;与供应商间存在着必不可少又高频的业务往来&#xff0c;而在汽车制造供应商之间&#xff0c;文件往来是确保业务顺利进行、沟通协作和质量控制的重要环节。这些文件往来涵盖了多个方面…

网络爬虫之爬虫原理

** 爬虫概述 Python网络爬虫是利用Python编程语言编写的程序&#xff0c;通过互联网爬取特定网站的信息&#xff0c;并将其保存到本地计算机或数据库中。 """ 批量爬取各城市房价走势涨幅top10和跌幅top10 """ ​ from lxml import etree impor…

通过本机端口映射VMware中虚拟机应用(例如同一局域网别人想远程连接你虚拟机中的数据库)

需要 虚拟机中安装一下达梦数据库&#xff0c;并且以后大家都连接你虚拟机中达梦数据库进行开发。。。。。。在不改动自己虚拟机配置&#xff0c;以及本地网卡任何配置的情况下如何解决&#xff1f;本虚拟机网络一直使用的NAT模式。 解决 找到NAT设置添加端口转发即可解决。…

高级IO—多路转接

&#x1f3ac;慕斯主页&#xff1a; 修仙—别有洞天 ♈️今日夜电波&#xff1a;Cupid - Twin Ver. (FIFTY FIFTY) - Sped Up Version 0:20━━━━━━️&#x1f49f;──────── 2:25 &#x1f504; …

【FFmpeg】视频与图片互相转换 ( 视频与 JPG 静态图片互相转换 | 视频与 GIF 动态图片互相转换 )

文章目录 一、视频与 JPG 静态图片互相转换1、视频转静态图片2、视频转多张静态图片3、多张静态图片转视频 二、视频与 GIF 动态图片互相转换1、视频转成 GIF 动态图片2、 GIF 动态图片转成视频 一、视频与 JPG 静态图片互相转换 1、视频转静态图片 执行 ffmpeg -i input.mp4 …

《浪潮之巅》:时代的巨轮与公司的兴衰

《浪潮之巅》是一部引人深思的作品&#xff0c;作者吴军通过对AT&T等公司的兴衰历程的叙述&#xff0c;展现了在科技浪潮之巅&#xff0c;公司如何成长、兴盛&#xff0c;并最终可能面临困境或转型。读完这部作品&#xff0c;我对公司的发展、企业经营者的战略眼光以及硅谷…

保姆级银河麒麟V10高级服务器离线安装mysql5.7数据库

离线在银河麒麟高级操作系统v10安装mysql5.7 下载mysql5.7 MySQL :: Download MySQL Community Server (Archived Versions) 2、把下载好的包上传到服务器 3、解压 [root1-0001 ~]# cd /data/mysql[root1-0001 mysql]# tar -zxvf mysql-5.7.44-linux-glibc2.12-x86_64.tar.gz…

artifactory配置docker本地存储库

​一、概述 本地 Docker 存储库是我们部署和托管内部 Docker 镜像的位置。实际上&#xff0c;它是一个 Docker 注册表&#xff0c;能够托管的 Docker 镜像的集合。通过本地存储库&#xff0c;你可以保存、加载、共享和管理自己的 Docker 镜像&#xff0c;而无需依赖于外部的镜像…