计算机网络课程设计(一)网络聊天程序的设计与实现

您所在的位置:网站首页 socket编程课程设计 计算机网络课程设计(一)网络聊天程序的设计与实现

计算机网络课程设计(一)网络聊天程序的设计与实现

2024-01-17 11:02| 来源: 网络整理| 查看: 265

实验题目

网络聊天程序的设计与实现

实验目的

 1、了解Socket通信的原理,学会使用Socket进行简单的网络编程,在此基础上编写一个聊天程序。

2、了解Qt编程,熟悉C++语言。

总体设计

 1、背景知识

套接字(socket)是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。套接字允许应用程序将I/O插入到网络中,并与网络中的其他应用程序进行通信。网络套接字是IP地址与端口的组合。

传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。用户数据报协议(UDP,User Datagram Protocol)是一种无需建立连接就可以发送封装的 IP 数据包的传输层通信协议。它不提供数据包分组、组装、对数据包进行排序、报文到达确认、流量控制等功能。

Qt 虽然经常被当做一个 GUI 库,用来开发图形界面应用程序,但这并不是 Qt 的全部;Qt 除了可以绘制漂亮的界面(包括控件、布局、交互),还包含很多其它功能,比如多线程、访问数据库、图像处理、音频视频处理、网络通信、文件操作等,这些 Qt 都已经内置了。

2、基本原理

Socket是一种“打开—读/写—关闭”模式的实现,服务器和客户端各自维护一个“文件”,在建立连接打开后,可以向文件写入内容供对方读取或者读取对方的内容,通讯结束时关闭文件。

Socket在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口,供应用层调用实现进程在网络中的通信。

Socket保证了不同计算机之间的通信,对于网站,通信模型是服务器与客户端之间的通信。两端都建立一个socket对象,然后通过socket对象对数据进行传输。通常服务器处于一个无限循环,等待客户端的连接。

3、模块介绍

(1)服务器端:监听本网络上的所有Ip,如有连接请求,则通过连接,与客户端进行一对一通信。

(2)客户端:通过给定的端口号与Ip地址连接到服务器端,与服务器端进行通信。

 4、设计步骤

(1)服务端

加载套接字库,创建套接字(QTcpSocket)绑定套接字到一个 IP 地址和一个端口上(bind())将套接字设置为监听模式等待连接请求(listen())请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept())用返回的套接字和客户端进行通信(send())返回,等待另一连接请求关闭套接字,关闭加载的套接字库

(2)客户端 

加载套接字库,创建套接字(QTcpSocket)向服务器发出连接请求(connect())和服务器端进行通信(send())关闭套接字,关闭加载的套接字库

 

详细设计

1、程序流程图

2、代码

 (1)服务器端

代码组成:

server.h

#ifndef SERVER_H #define SERVER_H #include #include #include QT_BEGIN_NAMESPACE namespace Ui { class server; } QT_END_NAMESPACE class server : public QMainWindow { Q_OBJECT public: server(QWidget *parent = nullptr); ~server(); private: Ui::server *ui; QTcpServer *Server; QTcpSocket *Socket; private slots: void Listen(); void send(); void newConnect(); void Read_data(); void DisConnect(); }; #endif // SERVER_H

 main.cpp

#include "server.h" #include int main(int argc, char *argv[]) { QApplication a(argc, argv); server w; w.show(); return a.exec(); }

 server.cpp

#include "server.h" #include "ui_server.h" #include server::server(QWidget *parent) : QMainWindow(parent) , ui(new Ui::server) { ui->setupUi(this); ui->Port->setText("2770"); connect(ui->pushButton_2,SIGNAL(clicked()),this,SLOT(Listen())); connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(send())); } server::~server() { delete ui; } void server::Listen(){ Server = new QTcpServer(); //int port = ui->Port->text().toInt(); if(!Server->listen(QHostAddress::Any, 2770)) { QMessageBox::information(this, "QT网络通信", "服务器端监听失败!"); return; } else { QMessageBox::information(this, "QT网络通信", "服务器监听成功!"); } connect(Server, SIGNAL(newConnection()), this, SLOT(newConnect())); } void server::send(){ qint64 writes=Socket->write(ui->textEdit->toPlainText().toLatin1()); bool Bool=Socket->flush(); if(writes==-1&&Bool!=1) { QMessageBox::warning(this, "QT网络通信", "发送数据失败,请重新发送!"); return; } ui->listWidget->addItem(QString(ui->textEdit->toPlainText()).toLocal8Bit()); ui->textEdit->clear(); } void server::Read_data(){ QByteArray array; array.resize(Socket->bytesAvailable());//根据可读数据来设置空间大小 array=Socket->readLine(); ui->listWidget->addItem("【客户端】:"+array); } void server::newConnect(){ Socket=Server->nextPendingConnection(); if(!Socket){ QMessageBox::warning(this, "warning", "未正确获取客户端连!"); return; } else { QMessageBox::information(this, "QT网络通信", "成功接受客户端的连接"); connect(Socket, SIGNAL(readyRead()), this, SLOT(Read_data())); connect(Socket, SIGNAL(disconnected()), this, SLOT(DisConnect())); } } void server::DisConnect(){ QMessageBox::information(this, "QT网络通信", "与客户端的连接断开"); return; }

 server.ui

server 0 0 465 556 server 20 410 301 51 340 440 75 23 发送 20 40 81 20 服务端端口号 110 40 113 20 240 40 75 23 初始化 20 80 301 311 0 0 465 23

 (2)客户端

代码组成:

client.h

#ifndef CLIENT_H #define CLIENT_H #include #include QT_BEGIN_NAMESPACE namespace Ui { class client; } QT_END_NAMESPACE class client : public QMainWindow { Q_OBJECT public: client(QWidget *parent = nullptr); ~client(); private: Ui::client *ui; private slots: void connection(); void send(); void read_data(); private: QTcpSocket *Socket; }; #endif // CLIENT_H

 main.cpp

#include "client.h" #include int main(int argc, char *argv[]) { QApplication a(argc, argv); client w; w.show(); return a.exec(); }

client.cpp

#include "client.h" #include "ui_client.h" #include #include #include client::client(QWidget *parent) : QMainWindow(parent) , ui(new Ui::client) { ui->setupUi(this); ui->Ip->setText("127.0.0.1"); ui->Port->setText("2770"); connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(connection())); connect(ui->pushButton_2,SIGNAL(clicked()),this,SLOT(send())); } client::~client() { delete ui; } void client::connection(){ Socket = new QTcpSocket(this); QString ip = ui->Ip->text(); // int port = ui->Port->text().toInt(); Socket->connectToHost(QHostAddress("127.0.0.1"), 2770); if(!Socket->waitForConnected(30000)) { QMessageBox::warning(this, "warning", "连接服务端失败!"); return; } QMessageBox::information(this,"Qt","success!"); connect(Socket, SIGNAL(readyRead()), this, SLOT(read_data())); } void client::send(){ //获取TextEdit控件中的内容 QString data=ui->send->toPlainText().toUtf8(); QByteArray ba=data.toLocal8Bit(); int sendRe = Socket->write(ba); bool bools=Socket->flush(); if(sendRe == -1&&bools!=1) { QMessageBox::information(this, "QT网络通信", "向服务端发送数据失败!"); return; } ui->listWidget->addItem(QString(ui->send->toPlainText()).toLocal8Bit()); ui->send->clear(); } void client::read_data(){ QByteArray array; array.resize(Socket->bytesAvailable());//根据可读数据来设置空间大小 array=Socket->readLine(); ui->listWidget->addItem("【服务端】:"+array); }

client.ui

client 0 0 373 573 client 20 30 61 21 服务端IP 20 70 81 21 服务端端口号 100 30 113 20 100 70 113 20 20 360 271 51 240 50 75 23 连接 250 430 75 23 发送 20 100 271 241 0 0 373 23 实验结果与分析

1、实验结果

 

 

 2、分析

首先必须要打开服务端,让服务器建立监听,然后再打开客户端,与服务器建立连接,客户端可以向服务器先发送消息,然后收到服务器的回复后又可以继续发送。有一个缺点是,必须要一来一回的聊天,客户端不能向服务器发送多条消息,同样服务器也不能。

小结与心得体会

本实验是第一个实验,刚开始拿到这题,完全没有一点思路,看了附录一后,逐渐对网络通信有了一点了解。在此之前我们没有接触过使用socket接口实现网络协议的一系列编程思想,对TCP和UDP的了解也仅限于理论知识,完全不会运用到实验中。在实验一中,我学会使用socket实现通信,也了解了一系列编程协议,同时从整体上对于winsock的使用流程有了更深一步的了解,通过阅读源码,对于TCP/IP协议在程序运行的实质和流程有了根深的理解。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3