请读者注意:该服务器,客户端实现的是简单的消息传递,并不能进行文件传输,在发送和接受消息的函数上进行了极大的简化;
(每一个合格的程序员都在耐心的分析每一行代码)
**服务器端:
头文件:**
#ifndef WIDGET_H
#define WIDGET_H
#include <QTcpServer>
#include <QTcpSocket>
#include <QString>
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
Ui::Widget *ui;
//##服务器##
private:
QTcpServer *tcpServer;
QTcpSocket *tcpSocket;
private slots:
void creatConnection(); //创建一个新连接
void useConnection(); //使用当前连接
void receiveMessage(); //接收消息
};
#endif // WIDGET_H
源文件:
//构造函数:
Widget::Widget(QWidget *parent) :QWidget(parent), ui(new Ui::Widget)
{
//服务器
tcpServer = new QTcpServer(this); //服务器监听类
if(!tcpServer->listen(QHostAddress::Any,12345)) //服务器监听本机所有IP的12345端口
{
qDebug() << tcpServer->errorString(); //Debug出错误信息
tcpServer->close(); //关闭监听
}
//关联信号,当有新到的连接时,执行槽函数
connect(tcpServer,SIGNAL(newConnection()),this,SLOT(creatConnection()));
/*
newConnection() 当有连接到来时发送该信号
*/
}
//creatConnection(): 槽函数
void Widget::creatConnection() //槽函数:创建连接
{
/*
注意: TcpServer类和TcpSocket类使用区别
我们一般使用TcpServer来监听端口;
使用TcpSocket来与客户端建立连接并传递数据;
*/
tcpSocket = new QTcpSocket(this); //socket类
//获取监听类里到来的 连接套接字
tcpSocket = tcpServer->nextPendingConnection();
tcpServer->close(); //关闭监听类
useConnection(); //在这个函数中使用连接套接字
}
//useConnection():槽函数
void Widget::useConnection()
{
//当函数执行到这里时,表明连接已经成功
//在界面textBrowser中插入纯文本,注意:插入的纯文本类型为QString;
ui->textBrowser->insertPlainText("connection succeed.\n");
//当缓冲区有数据可读时,执行槽函数
connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(receiveMessage()));
/*
readyRead(); //当有数据要读的时候,会触发该信号
有数据可读指的是,客户端发送数据已经存在于服务器端的缓冲区中,只要
缓冲区中存在数据了,该信号就会被触发
*/
}
//receiveMessage():槽函数
void Widget::receiveMessage() //槽函数:接收消息
{
//读取全部数据; 返回类型为QByteArray
QByteArray receiveDate = tcpSocket->readAll();
QString temp = receiveDate;
ui->textBrowser->insertPlainText(temp);
/*
插入纯文本是QString类型,我们用temp接收receiceDate;
*/
}
**服务器端已经编写完毕,下面是客户端:
头文件:**
#ifndef LANCLIENT_H
#define LANCLIENT_H
#include <QWidget>
#include <QTcpSocket>
namespace Ui {
class LANClient;
}
class LANClient : public QWidget
{
Q_OBJECT
public:
explicit LANClient(QWidget *parent = 0);
~LANClient();
private slots:
void useConnection();
void sendMessage();
private:
Ui::LANClient *ui;
private:
QTcpSocket *clientSocket;
QString message;
};
#endif // LANCLIENT_H
源文件:
//构造函数:
LANClient::LANClient(QWidget *parent) : QWidget(parent), ui(new Ui::LANClient)
{
ui->setupUi(this);
clientSocket = new QTcpSocket(this);
clientSocket->abort(); //断开之前的连接,保证当前连接是正确的
//连接到服务器,当前用的是测试ip
clientSocket->connectToHost("127.0.0.1",12345);
/*
如果是在两个不同的机子上,这里的地址应该写服务器的ip;
可以通过运行命令行,cmd,然后输入ipconfig查看服务器的ip
*/
//当连接成功时,会触发connected()这个信号,我们执行槽函数
connect(clientSocket,SIGNAL(connected()),this,SLOT(useConnection()));
}
//useConnection() : 槽函数
void LANClient::useConnection()
{
//向服务器发送消息
clientSocket->write("succeed!");
//获取远程主机(也就是服务器端)的ip地址和端口号,peer代表远程主机
QHostAddress address = clientSocket->QAbstractSocket::peerAddress();
qint16 port = clientSocket->QAbstractSocket::peerPort();
//控制台输出信息
qDebug() << address << endl << port << endl;
}