PC机与ARM板的聊天软件

 开始我们明确,此软件是在局域网里提供收发信息的聊天软件,也就是用网线连接,之后通过网线收发信息。既然如此,那么首先要把IP设在同一网段。这个工作之前篇“基于ARM的视频监控”已经有详细解释以及附图,在此不详述。之后,那就需要连接,连接当然要选择端口号,这个在程序已经设定好了,不用担心,这里我开的是9090端口,很显然这么大端口基本是没什么服务会用到的,所以是安全的。 然后数据传输的具体实现,首先,传输数据,当然要有个缓冲区,数据先传进缓冲区,之后在从缓冲区读取,不然数据没办法凭空传输,这就好比一个容器,当然这里缓冲区和caches是不一样的,caches是为了提高程序运行速度,当然如果有中断,或者多线程存在就要用volatile来定义了。 呵呵,扯远了。。。  这边我们事先要清空缓冲区,这是一件很重要的事,不然很有可能出现乱码等。不过如果数据和少,很可能自动传输不是很顺利,所以我们需要考虑到这点,那么需要人工加一句推代码,为了能让数据完全传输。  好了,大概流程就是这样,不过没做界面美化,要做的话,网上可以的荡美化包,有做好的。先贴效果图:

 

 

ARM端,初始监听状态。

 

PC机端,还没连接。

 

 

ARM端,已连接上。

PC机端输入IP连接上ARM端。

 

从PC端发送消息给ARM端,ARM端接受到消息。

 

ARM端发送来的消息在PC端显示。

 

 

PC端断开聊天。

 

 

 

断开后ARM端效果。

当然还有一些功能,比如说清屏,还有在ARM端也可以断开。

 

下面部分代码

PC端:

 

#include "socketwidget.h"
#include "ui_socketwidget.h"


/*客户端程序*/


SocketWidget::SocketWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::SocketWidget)
{
    ui->setupUi(this);
    socket = new QTcpSocket(this);
    connect(ui->pushButton_connect,SIGNAL(clicked()),this,SLOT(onConnect()));     //点击相关按钮触发相关槽函数
    connect(ui->pushButton_disconnect,SIGNAL(clicked()),this,SLOT(onDisconnect()));
    connect(ui->pushButton_send,SIGNAL(clicked()),this,SLOT(onSend()));
    connect(socket,SIGNAL(connected()),this,SLOT(imcoming()));    //管道建立后触发相关函数

    ui->pushButton_send->setShortcut(tr("Ctrl+R"));     //设置发送相关快捷键
}


/*连接按钮点击后的函数*/
void SocketWidget::onConnect()
{
    ui->pushButton_connect->setDisabled(true);    //设置相关按键使能与否
   // socket->connectToHost("localhost",9090);
    socket->connectToHost(QString(ui->lineEdit_socket->text()),9090);    //这里可以在lineEdit里写相应ip,如果只是测试只要输入localhost即可,且配置好端口
    if(!socket->waitForConnected(3000))              //等待3s,如果管道没接通那么则行{}内容
    {
        ui->pushButton_connect->setEnabled(true);
        ui->textEdit->append("connect failed!");
        return;

    }
    ui->pushButton_disconnect->setEnabled(true);  //设置相关按键使能与否
    ui->pushButton_send->setEnabled(true);
    ui->textEdit->append("connected to host");
  //  connect(socket,SIGNAL(readyRead()),this,SLOT(onread()));



}


/*点击Disconnect按钮后执行函数*/
void SocketWidget::onDisconnect()
{
    socket->abort();     //强行断开管道
    ui->textEdit->append("disconnected!");     //设置相关按键使能与否
    ui->pushButton_connect->setEnabled(true);
    ui->pushButton_disconnect->setDisabled(true);
    ui->pushButton_send->setDisabled(true);
   // connect(socket,SIGNAL(readyRead()),this,SLOT(onread()));
}


/*点击Send按钮后触发函数*/
void SocketWidget::onSend()
{
    socket->write(ui->lineEdit->text().toAscii());    //写信息进管道
    socket->flush();                //推信息
    ui->lineEdit->clear();



}


/*读信息函数*/
void SocketWidget::onread()
{

   char bufclient[100];                     //缓冲区
   memset(bufclient,0,sizeof(bufclient));   //清空缓冲区
   int lengthc = socket->bytesAvailable();   //从管道中计算传送数据长度
   socket->read(bufclient,lengthc);                //把指定长度数据从管道中放入缓冲区buf
   ui->textEdit->insertPlainText("\n");
   ui->textEdit->insertPlainText("server : ");         //显示相关发信息人,以及时间等
   ui->textEdit->insertPlainText(QDateTime::currentDateTime().toString("yyyy-mm-dd  "));
   ui->textEdit->insertPlainText(QTime::currentTime().toString("hh:mm:ss"));//textEdit文本框显示当前时间
   ui->textEdit->insertPlainText("\n");
   ui->textEdit->append(bufclient);            //显示信息
   ui->textEdit->insertPlainText("\n");

  //ui->textEdit->append(bufclient);


}


/*管道建立后,触发的相关函数*/
void SocketWidget::imcoming()
{

    ui->textEdit->append("connected.");
    connect(socket,SIGNAL(readyRead()),this,SLOT(onread()));   //准备,然后触发读信息槽
    connect(socket,SIGNAL(disconnected()),this,SLOT(enServerButton()));//管道断开,触发相关槽
}


/*断开后,各按键相关使能函数*/
void SocketWidget::enServerButton()
{
    ui->pushButton_connect->setEnabled(true);  //各按键使能
    ui->pushButton_disconnect->setDisabled(true);
    ui->pushButton_send->setDisabled(true);
 //   socket->abort();

}


/*析构函数*/
SocketWidget::~SocketWidget()
{
        delete socket;
        delete ui;
}

 

#ifndef SOCKETWIDGET_H
#define SOCKETWIDGET_H

#include <QWidget>
#include <QTcpSocket>
#include <QTextCodec>
#include <QTime>
#include <QDateTime>

namespace Ui {
    class SocketWidget;
}

class SocketWidget : public QWidget
{
    Q_OBJECT

public:
    explicit SocketWidget(QWidget *parent = 0);
    ~SocketWidget();

private:
    Ui::SocketWidget *ui;
    QTcpSocket *socket;
private slots:
    void onConnect();
    void onDisconnect();
    void onSend();
    void onread();
    void imcoming();
    void enServerButton();
};

#endif // SOCKETWIDGET_H

 

ARM端;

 

#include "serverwidget.h"
#include "ui_serverwidget.h"

/*服务器端程序*/

ServerWidget::ServerWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ServerWidget)
{
    ui->setupUi(this);
    server = new QTcpServer(this);
    if(!server->listen(QHostAddress::Any,9090))    //如果服务没监听到9090端口执行{}里信息
    {
        ui->textEdit->append("Listening filed!");
        return;
    }
     ui->textEdit->append("Listening...");
     connect(server,SIGNAL(newConnection()),this,SLOT(imcoming()));    //如果有新的连接信息newConnection(),触发imcoming()

  //   connect(ui->pushButton_connect,SIGNAL(clicked()),this,SLOT(onConnect()));
     connect(ui->pushButton_disconnect,SIGNAL(clicked()),this,SLOT(onDisconnect())); //断开触发相应操作
     connect(ui->pushButton_send,SIGNAL(clicked()),this,SLOT(onSend()));   //点击发送,触发相应槽

}

//void ServerWidget::onConnect()
//{
//    ui->pushButton_connect->setDisabled(true);
////    socket->connectToHost("localhost",9090);
//  //  if(!socket->waitForConnected(3000))
//  //  {
//        //ui->pushButton_connect->setEnabled(true);
//        ui->textEdit->append("connect failed!");
//        return;

//  //  }
//    ui->pushButton_disconnect->setEnabled(true);
//    ui->pushButton_send->setEnabled(true);
//    ui->textEdit->append("connect to host");


//}


/*点击断开连接按钮后的相应操作函数*/
void ServerWidget::onDisconnect()
{
   // socket->disconnect();
    socket->abort();                       //让管道失效
    ui->textEdit->append("disconnected!");   //显示断开信息
    //ui->pushButton_connect->setEnabled(true);
    ui->pushButton_disconnect->setDisabled(true);  //设置相应按键使能与否,防止错误点击
    ui->pushButton_send->setDisabled(true);
 //   connect(socket,SIGNAL(disconnected()),this,SLOT(enServerButton()));
}


/*点击发送按钮后相应操作函数*/
void ServerWidget::onSend()
{
    socket->write(ui->lineEdit->text().toAscii());   //把相关数据送入管道
    socket->flush();                      //防止数据较少不能自动发送,所以推一把
    ui->lineEdit->clear();            //清除lineEdit里信息,为了界面效果

}


/*新连接信息来之后(再次按下connect按钮(包括第一次))触发的相关函数*/
void ServerWidget::imcoming()
{
    socket = server->nextPendingConnection();   //把客户端的socket端口存入到服务器端的socket端口,理论上只有一个socket
    ui->textEdit->append("connected.");
    ui->pushButton_disconnect->setEnabled(true);    //设置相应按键使能与否,防止错误点击,以及逻辑效果
    ui->pushButton_send->setEnabled(true);
    connect(socket,SIGNAL(readyRead()),this,SLOT(onread()));   //管道准备好读取数据,触发onread()
    connect(socket,SIGNAL(disconnected()),this,SLOT(enServerButton()));  //管道没连接,那么出发enServerButton()设置相关按键使能与否
}


/*管道断开设置相关按钮使能与否函数*/
void ServerWidget::enServerButton()
{
    ui->pushButton_disconnect->setDisabled(true);
    ui->pushButton_send->setDisabled(true);
 //   socket->abort();

}


/*读信息函数*/
void ServerWidget::onread()
{

   char buf[100];                            //暂存数据中转站
   memset(buf,0,sizeof(buf));               //先清0
   int length = socket->bytesAvailable();   //从管道中计算传送数据长度
   socket->read(buf,length);                //把指定长度数据从管道中放入缓冲区buf
   ui->textEdit->insertPlainText("\n");       //显示通信对象,以及时间等信息
   ui->textEdit->insertPlainText("socket : ");
   ui->textEdit->insertPlainText(QDateTime::currentDateTime().toString("yyyy-mm-dd  "));
   ui->textEdit->insertPlainText(QTime::currentTime().toString("hh:mm:ss"));//textEdit文本框显示当前时间
   ui->textEdit->insertPlainText("\n");
   ui->textEdit->append(buf);
   ui->textEdit->insertPlainText("\n");
  // ui->textEdit->append(buf);


}

/*析构函数*/
ServerWidget::~ServerWidget()
{
    delete server;   //new之后最好是delete下,不然很容易产生野指针
    delete ui;
}

 

#ifndef SERVERWIDGET_H
#define SERVERWIDGET_H

#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>
#include <QTextCodec>
#include <QTime>
#include <QDate>

namespace Ui {
    class ServerWidget;
}

class ServerWidget : public QWidget
{
    Q_OBJECT

public:
    explicit ServerWidget(QWidget *parent = 0);
    ~ServerWidget();

private:
    Ui::ServerWidget *ui;
    QTcpServer *server;
    QTcpSocket *socket;
private slots:
    void imcoming();
    void onread();

private slots:
   // void onConnect();
    void onDisconnect();
    void onSend();
    void enServerButton();
};

#endif // SERVERWIDGET_H

 

当然这个软件也可以用于局域网PC与PC机之间,或者ARM板与ARM板之间。  经过测试。

提供源码链接:

http://files.cnblogs.com/li-zi/TestTcpSocket.rar PC端源码

http://files.cnblogs.com/li-zi/TestTcpServer.rar ARM端源码

转载于:https://www.cnblogs.com/li-zi/archive/2012/12/03/2800400.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值