一、基于Qt的TCP通讯
- 服务器和客户端的框图
1. Qt 工程包含以下
QT += network
CONFIG += C++11
-
Service端
1. 服务器(Server)包含2个头文件
#include <QTcpServer>
#include <QTcpSocket>
2. 在class Tcp_Server 的 private 内创建2个指针:
QTcpServer *tcpServer;
QTcpSocket *tcpSocket;
3. 构造函数处理:
Tcp_Server::Tcp_Server(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Tcp_Server)
{
ui->setupUi(this);
this->setWindowTitle("TCP Server ming.liu@2020-06-21");
tcpSocket = NULL;
tcpServer = NULL;
ui->textEdit_read->setReadOnly(true);
tcpServer = new QTcpServer(this);
tcpServer->listen(QHostAddress::Any, 8888); //Any默认绑定网口的所有ip地址
/* 绑定ip和端口号 */
connect(tcpServer, &QTcpServer::newConnection,
[=]()
{
//取出建立好连接的套接字
tcpSocket = tcpServer->nextPendingConnection();
//获取客户端的ip和端口
QString ip = tcpSocket->peerAddress().toString();
uint16_t port = tcpSocket->peerPort();
QString temp = QString("[%1:%2]:成功连接").arg(ip).arg(port);
ui->textEdit_read->setText(temp);
//接收客户端发来的数据,并显示
connect(tcpSocket,&QTcpSocket::readyRead,
[=]()
{
QByteArray array = tcpSocket->readAll();
ui->textEdit_read->append(array);
}
);
}
);
}
4. 服务器(Server)端发送
void Tcp_Server::on_BT_send_clicked()
{
if(tcpSocket == NULL)
{
return;
}
//获取编辑区内容
QString str = ui->textEdit_write->toPlainText();
tcpSocket->write(str.toUtf8().data()); //server发送
}
5. 服务器(Server)断开连接
void Tcp_Server::on_BT_disconnect_clicked()
{
//主动和对方断开连接
tcpSocket->disconnectFromHost();
tcpSocket->close(); //加上此句,在Debug区可以看到打印信息
ui->textEdit_read->setText("已断开");
}
-
Client 端
1. 包含头文件(注意:服务器是包含2个头文件)
#include <QTcpSocket>
2. 在 class tcpClient 的private下创建 QTcpSocket 的对象指针
QTcpSocket *tcpSocket;
如下图所示:
3. 构造函数处理 (重点)
tcpClient::tcpClient(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::tcpClient)
{
ui->setupUi(this);
this->setWindowTitle("TCP Client");
tcpSocket = NULL;
//分配空间,指定父对象
tcpSocket = new QTcpSocket(this); // 1--实例化tcpSocket 的对象
connect(tcpSocket, &QTcpSocket::connected, // 2--已连接的信号槽
[=]()
{
ui->textEdit_read->setText("已连接");
}
);
connect(tcpSocket,&QTcpSocket::readyRead, // 3-- 接收数据处理
[=]()
{
//获取对方发送的内容
QByteArray array = tcpSocket->readAll();
//显示到编辑区
ui->textEdit_read->append(array);
}
);
}
4. connect 服务器
void tcpClient::on_BT_connect_clicked()
{
//获取服务器ip和端口
QString ip = ui->lineEdit_ip->text();
qint16 port = ui->lineEdit_port->text().toInt();
//主动和服务器建立连接
tcpSocket->connectToHost(QHostAddress(ip),port);
}
5. 向服务器发送数据
void tcpClient::on_BT_send_clicked()
{
//获取待发送内容
QString str = ui->textEdit_write->toPlainText();
tcpSocket->write(str.toUtf8().data());
}
6. 与服务器断开连接
void tcpClient::on_BT_disconnect_clicked()
{
//主动和对方断开连接
tcpSocket->disconnectFromHost();
tcpSocket->close(); //加上此句,在Debug区可以看到打印信息
ui->textEdit_read->setText("已断开");
}
所实现的Demo
资源代码:https://gitee.com/the_wind_is_clear/QtSerialDemo/blob/QT_socket/README.md
二、基于Linux的socket通讯
下面展示的是韦东山的进程间使用socket的示例Demo
2.1 服务器(server)端
/**********************************************************************
* 功能描述: 1.server打印client发送过来的字符串,并将该字符串回发给client
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 无
***********************************************************************/
server.c
/**********************************************************************
* 功能描述: 1.server打印client发送过来的字符串,并将该字符串回发给client
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 无
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2020/05/16 V1.0 zh(ryan) 创建
***********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/un.h>
int main(int argc, char *argv[])
{
int lfd ,ret, cfd;
struct sockaddr_un serv, client;
socklen_t len = sizeof(client);
char buf[1024] = {0};
int recvlen;
//创建socket
lfd = socket(AF_LOCAL, SOCK_STREAM, 0);
if (lfd == -1) {
perror("socket error");
return -1;
}
//如果套接字文件存在,删除套接字文件
unlink("server.sock");
//初始化server信息
serv.sun_family = AF_LOCAL;
strcpy(serv.sun_path, "server.sock");
//绑定
ret = bind(lfd, (struct sockaddr *)&serv, sizeof(serv));
if (ret == -1) {
perror("bind error");
return -1;
}
//设置监听,设置能够同时和服务端连接的客户端数量
ret = listen(lfd, 36);
if (ret == -1) {
perror("listen error");
return -1;
}
//等待客户端连接
cfd = accept(lfd, (struct sockaddr *)&client, &len);
if (cfd == -1) {
perror("accept error");
return -1;
}
printf("=====client bind file:%s\n", client.sun_path);
while (1) {
recvlen = recv(cfd, buf, sizeof(buf), 0);
if (recvlen == -1) {
perror("recv error");
return -1;
} else if (recvlen == 0) {
printf("client disconnet...\n");
close(cfd);
break;
} else {
printf("server recv buf: %s\n", buf);
send(cfd, buf, recvlen, 0);
}
}
close(cfd);
close(lfd);
return 0;
}
2.2 客户端(Client)
/**********************************************************************
* 功能描述: 1.client从标准输入获取到一个字符串,然后将这个字符串发送给server
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 无
***********************************************************************/
/**********************************************************************
* 功能描述: 1.client从标准输入获取到一个字符串,然后将这个字符串发送给server
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 无
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2020/05/16 V1.0 zh(ryan) 创建
***********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/un.h>
int main(int argc, char *argv[])
{
int lfd ,ret;
struct sockaddr_un serv, client;
socklen_t len = sizeof(client);
char buf[1024] = {0};
int recvlen;
//创建socket
lfd = socket(AF_LOCAL, SOCK_STREAM, 0);
if (lfd == -1) {
perror("socket error");
return -1;
}
//如果套接字文件存在,删除套接字文件
unlink("client.sock");
//给客户端绑定一个套接字文件
client.sun_family = AF_LOCAL;
strcpy(client.sun_path, "client.sock");
ret = bind(lfd, (struct sockaddr *)&client, sizeof(client));
if (ret == -1) {
perror("bind error");
return -1;
}
//初始化server信息
serv.sun_family = AF_LOCAL;
strcpy(serv.sun_path, "server.sock");
//连接
connect(lfd, (struct sockaddr *)&serv, sizeof(serv));
while (1) {
fgets(buf, sizeof(buf), stdin);
send(lfd, buf, strlen(buf)+1, 0);
recv(lfd, buf, sizeof(buf), 0);
printf("client recv buf: %s\n", buf);
}
close(lfd);
return 0;
}