qt5 c语言开发安卓应用程序,c – 如何在Qt中编写Client-Server应用程序并实现简单协议...

也许这是一个愚蠢的问题,实际上它的吸引力,或者Qt只是让我复杂化.

这是事情:

在编写客户端 – 服务器应用程序时,我习惯于

java,而且非常简单.我想在C中做同样的事情(我对C本身非常熟悉),我选择学习Qt.我尝试在qt中编写一些应用程序,但取得了部分成功.

困扰我的第一件事是信号和插槽.我知道如何在GUI编程中使用它们,但它让我对网络感到困惑.阻塞有问题.当我在java中调用BufferedReader的readLine()方法时,它会阻塞,直到它从套接字连接接收到行.在Qt我必须确保每次都有可用的行,并在没有行时处理它.

当我将QSocket的错误信号连接到我的一些自定义插槽时,当服务器发送最后一行并关闭连接时会发出信号,而在客户端的插槽/函数中,我从未读过最后一行.这是我到目前为止遇到的一些问题.

插槽和检查是否有可用的数据让我感到困惑,因为我必须实现最简单的协议.

重要部分:

我试图在互联网上找到一个很好的例子,但问题是所有的例子都是复杂的.有没有人可以告诉我如何编写简单的客户端 – 服务器应用程序.服务器只接受一个客户端.客户端发送包含命令的文本行.如果命令是“ADD”或“SUB”,则服务器发送“SUP”表示支持该命令.否则它发送“UNS”并关闭连接.如果客户收到“SUP”,它会发送到包含要减去或添加的数字的更多行.服务器响应结果并关闭连接.

我知道C需要更多编码,但在Java中这只需要5分钟,因此在C中编写它也不需要花很长时间.

我相信这个例子对于想要在Qt中学习网络的人来说非常有价值.

编辑:

这是我尝试制作应用程序(如上所述):

这是服务器部分:

#ifndef TASK_H

#define TASK_H

#include

#include

class Task : public QObject

{

Q_OBJECT

public:

Task(QObject *parent = 0) : QObject(parent) {}

public slots:

void run();

void on_newConnection();

void on_error(QAbstractSocket::SocketError);

signals:

void finished();

private:

QTcpServer server;

};

#endif // TASK_H

void Task::run()

{

connect(&server,SIGNAL(newConnection()),this,SLOT(on_newConnection()));

connect(&server,SIGNAL(acceptError(QAbstractSocket::SocketError)),this,SLOT(on_error(QAbstractSocket::SocketError)));

if(server.listen(QHostAddress::LocalHost, 9000)){

qDebug() << "listening";

}else{

qDebug() << "cannot listen";

qDebug() << server.errorString();

}

}

void Task::on_newConnection(){

std::cout << "handeling new connection...\n";

QTcpSocket* socket = server.nextPendingConnection();

QTextStream tstream(socket);

while(!socket->canReadLine()){

socket->waitForReadyRead((-1));

}

QString operation = tstream.readLine();

qDebug() << "dbg:" << operation;

if(operation != "ADD" && operation != "SUB"){

tstream << "UNS\n";

tstream.flush();

socket->disconnect();

return;

}

tstream << "SUP\n";

tstream.flush();

double op1,op2;

while(!socket->canReadLine()){

socket->waitForReadyRead((-1));

}

op1 = socket->readLine().trimmed().toDouble();

qDebug() << "op1:" << op1;

while(!socket->canReadLine()){

socket->waitForReadyRead(-1);

}

op2 = socket->readLine().trimmed().toDouble();

qDebug() << "op2:" << op2;

double r;

if(operation == "ADD"){

r = op1 + op2;

}else{

r = op1 - op2;

}

tstream << r << "\n";

tstream.flush();

qDebug() << "result is: " << r;

socket->disconnect();

}

void Task::on_error(QAbstractSocket::SocketError ){

qDebug() << "server error";

server.close();

}

这是客户端(标题类似于服务器的所以我不会发布它):

void Task::run()

{

QTcpSocket socket;

std::string temp;

socket.connectToHost(QHostAddress::LocalHost,9000);

if(socket.waitForConnected(-1))

qDebug() << "connected";

else {

qDebug() << "cannot connect";

return;

}

QTextStream tstream(&socket);

QString op;

std::cout << "operation: ";

std::cin >> temp;

op = temp.c_str();

tstream << op << "\n";

tstream.flush();

qDebug() << "dbg:" << op << "\n";

while(!socket.canReadLine()){

socket.waitForReadyRead(-1);

}

QString response = tstream.readLine();

qDebug() << "dbg:" << response;

if(response == "SUP"){

std::cout << "operand 1: ";

std::cin >> temp;

op = temp.c_str();

tstream << op + "\n";

std::cout << "operand 2: ";

std::cin >> temp;

op = temp.c_str();

tstream << op + "\n";

tstream.flush();

while(!socket.canReadLine()){

socket.waitForReadyRead(-1);

}

QString result = tstream.readLine();

std::cout << qPrintable("result is: " + result);

}else if(response == "UNS"){

std::cout << "unsupported operatoion.";

}else{

std::cout << "unknown error.";

}

emit finished();

}

>我能做得更好吗?

>在类似情况下有哪些好的做法?

>当使用阻塞(不是信号/插槽机制)时,当另一侧关闭连接时,处理事件的最佳方法是什么?

>有人可以重写这个以使它看起来更专业(我只是看看它应该是什么样子,因为我认为我的解决方案远非完美)?

>有人可以使用信号和插槽重写吗?

谢谢.

对不起,我的英文,可能是愚蠢的:)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目录 第一部分 Windows编程基础 第1章 HelloWindowsCE 1.1 WindowsCE标准Windows的差别 1.1.1 WindowsCE和标准Windows的差别 1.1.2 资源有限的WindowsCE设备 1.1.3 Unicode编码 1.1.4 组件化设计 1.1.5 Win32子集 1.2 仍然是Windows编程 1.3 第一个WindowsCE应用程序 1.3.1 创建第一个WindowsCE应用程序 1.3.2 运行程序 1.3.3 出了什么问题 1.4 Hello2程序 1.5 剖析窗口应用程序 1.5.1 窗口 1.5.2 窗口类 1.5.3 窗口过程 1.5.4 消息的生命期 1.5.5 注册窗口 1.5.6 创建窗口 1.5.7 消息循环 1.5.8 窗口过程 1.6 HelloCE 1.7 运行HelloCE 第2章 在屏幕上绘图 2.1 绘图基础 2.1.1 合法和非法区域 2.1.2 设备上下文 2.2 文本输出 2.2.1 设备上下文属性 2.2.2 TextDemo示例程序 2.2.3 字体 2.2.4 未完成的任务 2.3 位图 2.3.1 设备相关位图 2.3.2 设备无关位图 2.3.3 DIB区域 2.3.4 绘制位图 2.3.5 AlphaBlending 2.4 线和形体 2.4.1 线 2.4.2 形体 2.4.3 填充函数 2.4.4 Shapes示例程序 第3章 输入:键盘、鼠标和触摸屏 3.1 键盘 3.1.1 输入焦点 3.1.2 键盘消息 3.1.3 键盘函数 3.1.4 KeyTrac示例程序 3.2 鼠标和触摸屏 3.2.1 鼠标消息 3.2.2 使用触摸屏 3.2.3 TicTacl示例程序 第4章 窗口、控件和菜单 4.1 子窗口 4.2 窗口管理函数 4.2.1 枚举窗口 4.2.2 寻找窗口 4.2.3 移动窗口 4.2.4 编辑窗口结构的内容 4.3 窗口控件 4.3.1 使用控件工作 4.3.2 按钮控件 4.3.3 编辑控件 4.3.4 列表框控件 4.3.5 组合框控件 4.3.6 静态文本控件 4.3.7 滚动条控件 4.3.8 控件和颜色 4.4 菜单 4.5 资源 4.5.1 资源脚本 4.5.2 图标 4.5.3 加速键 4.5.4 位图 4.5.5 字符串 4.6 DOIView示例程序 第5章 通用控件与WindowsCE 5.1 通用控件编程 5.2 通用控件 5.2.1 命令栏 5.2.2 其他菜单控件 5.2.3 日历控件 5.2.4 时间日期选择器控件 5.2.5 列表视图控件 5.2.6 CapEdit控件 5.3 其他一些通用控件 5.4 不支持的通用控件 第6章 对话框和属性表 6.1 对话框 6.1.1 对话框资源模板 6.1.2 创建对话框 6.1.3 对话框过程 6.1.4 非模态的对话框 6.1.5 属性表 6.1.6 通用对话框 6.2 DlgDemo范例程序 第二部分WindOWSCE编程 第7章 内存管理 7.1 内存基础知识 7.1.1 关于RAM 7.1.2 关于ROM 7.1.3 关于虚拟内存 7.1.4 应用程序的地址空间 7.2 不同类型的内存分配 7.2.1 虚拟内存 7.2.2 堆 7.2.3 本地堆 7.2.4 独立堆 7.2.5 栈 7.2.6 静态数据 7.2.7 字符串资源 7.2.8 选择适当的内存类型 7.2.9 管理低内存状态 第8章 模块、进程和线程 8.1 模块 8.2 进程 8.2.1 创建进程 8.2.2 终止进程 8.2.3 其他进程 8.3 线程 8.3.1 系统调度器 8.3.2 创建线程 8.3.3 设置和查询线程优先级 8.3.4 设置线程时间片 8.3.5 挂起和恢复线程 8.4 纤程 8.5 线程本地存储 8.6 同步 8.6.1 事件 8.6.2 等待 8.6.3 信号量 8.6.4 互斥量 8.6.5 复制同步旬柄 8.6.6 临界区 8.6.7 互锁变量访问 8.7 进程间通信 8.7.1 查找其他进程 8.7.2 WM-COPYDATA 8.7.3 命名内存映射对象 8.7.4 点对点消息队列 8.7.5 使用文件和数据库通信 8.8 XTalk示例程序 8.9 异常处理 8.9.1 C++异常处理 8.9.2 Win32异常处理 第9章 WindLOWSCE文件系统 9.1 WindowsCE文件系统API 9.1.1 标准文件VO 9.1.2 内存映射文件 9.1.3 文件系统浏览 9.2 存储处理 9.2.1 对象存储 9.2.2 使用文件API来访问卷 9.2.3 存储管理器 第10章 注册表 10.1 注册表组织 l0.2 注册表API l0.2.1 打开和创建主键 10.2.2 读取注册表值 10.2.3 写人注册表值 10.2.4 删除注册表主键和值 10.2.5 枚举注册表主键 l0.2.6 刷新注册表主键 10.2.7 注册表改动通知 10.2.8 RegView示例程序 第11章 WindowsCE数据库 11.1 两种数据库 11.2 基本概念 11.3 数据库.API 第12章 通知 12.1 用户通知 12.2 计时器事件通知 12.3 系统事件通知 12.4 NoteDemo示例程序 12.5 查询已设定的通知 12.6 气泡通知 12.6.1 添加气泡通知 12.6.2 修改气泡通知 12.6.3 删除气泡通知 第三部分高级WindOWSCE 第13章 windOWSCE网络 13.1 Windows网络支持 13.1.1 WNet函数 13.1.2 ListNet示例程序 13.2 TCP/IP编程 13.2.1 套接字编程 13.2.2 阻塞套接字与非阻塞套接字 第14章 设备间通信 14.1 红外通信 14.1.1 红外基础 14.1.2 设备发现 14.1.3 发布红外服务 14.1.4 查询和设置红外套接字选项 14.1.5 MySquirt示例程序 14.2 蓝牙 14.2.1 蓝牙协议栈 14.2.2 蓝牙发现 14.2.3 发布一个服务 14.2.4 通过WinSock进行蓝牙通信 14.2.5 通过虚拟COM端口进行蓝牙通信 14.2.6 BtSquirt示例程序 第15章 系统程序设计 15.1 WindowsCE的内存体系结构 15.1.1 应用程序的地址空间 15.1.2 内核态的地址空间 15.2 编写跨平台的WindowsCE应用程序 15.2.1 平台与操作系统版本 15.2.2 编译时的版本确定 15.2.3 显式链接 15.2.4 运行时的版本检测 15.3 电源管理 15.3.1 关机的含义 15.3.2 查询电源状态 15.3.3 电源管理器 15.3.4 不使用电源管理器来管理电源 第16章 串行通信 16.1 基本串行通信 16.1.1 打开和关闭串行端口 16.1.2 读写串行端口 16.1.3 异步串行I/O 16.1.4 配置串行端口 16.1.5 设置端口的超时值 16.1.6 查询串行驱动程序的能力 16.1.7 控制串行端口 16.1.8 清除错误并查询状态 16.1.9 保持活动状态 16.2 CeChat示例程序 第17章 设备驱动程序和服务 17.1 驱动程序基础 17.1.1 驱动程序的名称 17.1.2 设备驱动加载过程 17.1.3 枚举活动的驱动? 17.1.4 读写设备驱动 17.2 编写WindowsCE流式设备驱动 17.2.1 流式驱动的入口函数 17.2.2 缓冲区管理 17.2.3 驱动程序接口类 17.2.4 设备驱动程序的电源管理 17.3 设备驱动程序的构建 17.3.1 DebugZone 17.3.2 Gentle驱动程序示例 17.4 服务 17.4.1 服务的体系结构 17.4.2 服务的生命周期 17.4.3 应用程序对服务的控制 17.4.4 服务DLL的人口函数 17.4.5 服务的IOCTL命令 17.4.6 超级服务 17.4.7 Services.exe的命令行 17.4.8 TickSrv示例服务

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值