当前课程知识点:基于Linux的C++ >  第十五讲 网络编程 >  15.4 套接字(二) >  LinuxCPP1504

返回《基于Linux的C++》慕课在线视频课程列表

LinuxCPP1504在线视频

LinuxCPP1504

下一节:LinuxCPP1505

返回《基于Linux的C++》慕课在线视频列表

LinuxCPP1504课程教案、知识点、字幕

我们看具体的实现代码

我们这里边使用本地套接字

实现服务器端和客户端

看看服务器端是怎么实现的

我们实现一个函数

Serve() 服务函数

返回值是一个bool量

它接受是一个客户套接字的一个参数

这个函数呢将负责持续地读取信息

直到这个套接字被关闭

或者连接这个套接字的那个客户

发出“quit”这个消息

如果你没有发出“quit”消息

或者这个套接字没关闭那么

这个服务器就不断地

从套接字里把这个信息拿到

它就认为里面你可能有信息

它就不断地朝外拿信息

就这个意思

如果是套接字被关闭了

那么返回值就是true

如果是用户

发出了一个“quit”这个请求

我们的返回值就设成false

就是说我不服务了

函数本身内部主代码是while( true )

它是个无限循环

不断地从里面取数据

它不停的 永远不停的

除非套接字被关了

除非用户说我不玩了 quit

否则它不返回的

while( true ) 从里面取数据

通过read()这个系统调用

从这个套接字里边

把这个数据取出来

如果返回值是0

说明这个套接字被关闭了

我们就return true

这个函数就算做完了

但是我们这个服务器并不能关 对吧

就这个意思

取到这个数据之后

我们就会把它输出

然后看用户输入的那个数据

是不是“quit”

如果是“quit”我就不玩了

我就return false

Serve()就算结束了

套接字的服务就算结束了

任何一个客户发出一个“quit”消息

这个套接字服务器就关掉

就这个意思

定义一个套接字地址的

一个结构体的一个变量

定义一个name

这是一个套接字地址的名

定义一个serving这样的一个变量

用来表达服务器是不是持续在运行

然后我们调用socket()创建这个套接字

使用PF_LOCAL

表明创建的是一个本地套接字

设定好这个服务器的具体的性质

把它路径啊什么的都设定号

然后绑定这个套接字

调用bind()函数把这个套接字fd

和这个地址给绑定起来

这个就算把本地服务器

和套接字给挂上了

绑定了完之后

我们侦听客户的连接

就看有没有客户

通过我们这个套接字

向这边发送消息了

侦听到了之后

我们重复地接受这个连接

直到某个客户发出“quit”的消息

我才over 我才结束

所以这个主体循环就是while( serving )

当它是处于服务状态的时候

那么定义一个客户的地址

定义一个客户的套接字的文件描述符

然后我们就接受这个客户的连接

形成一个客户的套接字fd

在此之后 提供这个服务

从那个客户中读取数据

或者向那个客户中发送数据

都可以通过Serve()这个函数去做了

做完之后 关闭掉这个套接字

这次连接就算结束了

所以我们就关闭这个套接字

然后进一步去循环

看是不是继续要提供服务

如果是 我们就继续地接受它的服务

然后提供服务 然后关闭

继续 循环

它是按照这个模式

除非一个客户连接发出一个“quit”请求

当接受到“quit”请求之后

我就停止服务

最后别忘了close我们的套接字

关闭我们的套接字文件描述符

最后别忘了用unlink

删除套接字文件

这是本地套接字设立的服务器端

我们还需要写一个连接它的客户端

在客户端里面

我实现一个函数叫SendMsg()

发送消息

就向一个对应的套接字里边

发送一个特定的字符串

写一个数据进去

函数实现很简单

这我们就不解释了

我们看主函数

我仍然需要创建一个套接字

socket( PF_LOCAL, SOCK_STREAM, 0 )

然后设定好它的存储服务器的名字

在套接字地址里边设定好它的名字

设定好名字之后 连接

调用connect()去连接那个服务器

传设定的信息 连接进去

连接成功 发送消息 SendMsg()

就向它发送 就OK了

发送完close() 关闭

这就是我们的客户端

这两个程序你分别地编译

生成可执行文件

那么我们怎么运行它呢

那么你分别编译

客户端和服务器端两个程序

形成两个可执行文件

然后你进入服务器端的那个程序的目录

在终端里面就输入“./server /tmp/socket”

这样的话

就会启动这个套接字的服务器

并且在“/tmp”这个目录下

给你构造一个套接字的文件

服务器和客户端

就会通过这个文件进行通讯

就是这个意思

“./server”就是那个服务器端的程序名字

“/tmp/socket”就是这个本服务器

启动以后的套接字文件名

然后你进入客户端的程序目录

在一个新的终端里面输入

“./client /tmp/socket”

后面跟着一个字符串“Hello World!”

什么意思呢

就是启动我们这个客户端

向套接字“/tmp/socket”

里边输入一串信息“Hello World!”

那么当这个服务器接受到

这个客户的连接请求之后

它接受到了这个字符串

它就会把这个字符串

在屏幕上输出出来

表示它接受到了这个信息

如果你要停止这个服务器

就在客户端里面输入命令

“./client /tmp/socket”

后面输出一个命令串“quit”退出

那个套接字就会停止

这是我们的本地套接字的实现

接下来一个例子呢

就是网络的实现

我们这里边

给出网络套接字的客户端的实现

服务器端的实现我们没有给出来

那是我们最后的大作业

你要做的事

网络套接字和本地套接字

理论上讲实现上几乎没有差别

它就是那个属性的设置的问题

剩下的基本上没有差别

只不过因为我们网络上数据的传输

大部分的时候

我们要生成HTML文档

那个时候生成HTML文档

或解析HTML文档会比较麻烦一点

其实除此之外和本地套接字的实现

基本上差不多

步骤是非常非常类似的

首先 我们可以写一个函数叫GetHomePage()

来获取Web服务器的主页

我们这里边只是简单地

向它发送一个“GET /”命令

就是“GET /\n”

你就把这个命令发到了Web服务器上

Web服务器接受到这个命令以后

就会把它的主页内容传递给你

就这个意思

那么我们在这里边

就向它套接字里写入这个请求

写入这个请求之后

立即就从套接字里边

把它反馈的信息读出来

我们无限地读

做了一个无限循环去读它

一直读 一直读

只要有信息 我们就把它读出来

就这个意思

我们读出来以后

我们就把它呈现出来

你可以向标准输出流里面输出

你可以向文件里输出

你可以弄了一个网页浏览器

然后就在它那个工作区

或者那个画布

就在它的工作区里边把它绘制出来

总之你读到了这个信息

你想用什么方式处理它

就按什么方式处理它

如果读到的数据是0

就说明什么呢

说明没有数据可读了

所以我们就return

就获取它的主页

接下来就是网络套接字的

那个客户端的主函数

在实现上实际上和

那个本地套接字的客户端非常得相似

但只不过呢

因为我们这里面要访问是网络资源

所以它实际上是用

网络的那个地址传递信息的

所以这个地方设计的时候

会有一些额外的函数调用

我们会调用socket()

创建这样的一个套接字

然后设定它的网络传输属性

这是PF_INET、AF_INET

不是PF_LOCAL、AF_LOCAL了

这是网络套接字

不是本地套接字了

然后呢 传一个参数进来了argv[1]

就是你执行程序的时候

你要把那个HTTP请求

那个HTTP的地址

那个网址作为这个程序(客户端程序)

的参数传进来的

所以我们这里调用gethostbyname()

得到那个套接字的主机的名字

然后还调用htons()得到它的端口

设定它的端口

我们主机端口一般我们设成80

OK 就这个意思

设定它的端口

然后我们connect()

连接那个套接字

如果成功地连接

哎呀 没啥可说的

我们就读取它的信息就行了

调用GetHomePage()

获取它的主页就完了

如果没有成功连接

那就是网站不能用

没有提供这个服务

诸如此类 不管怎么样

那我们就退出 这是很典型

这就是网络套接字的客户端

我这个程序运行以后

我们就尝试着用它去访问了

www.tsinghua.edu.cn这个网站

然后它返回了HTML的文本

就这个模样

因为这是一个文本界面的Web客户端

所以你也指望

给你显示什么图形啊什么的

那些东西都不存在

只有最简单的文本信息

所以这个网页超级简单

就是什么

最基本的报头信息

找到了这个文档

然后告诉你

它是清华Web服务器1.2.1

就这么最简单的信息传过来了

但不管怎么样

这个网址我们访问到了

它确实反馈回来了信息

这就是我们的

网络套接字的客户端的实现

基于Linux的C++课程列表:

第一讲 C/C++基本语法元素

-1.1 提纲

--LinuxCPP0101

-1.2 程序设计的基本概念

--LinuxCPP0102

-1.3 简单C/C++程序介绍

--LinuxCPP0103

-1.4 程序设计的基本流程

--LinuxCPP0104

-1.5 基本语法元素

--LinuxCPP0105

-1.6 程序设计风格

--LinuxCPP0106

-1.7 编程实践

--LinuxCPP0107

-第一讲 C/C++基本语法元素--编程实践提交入口

第二讲 程序控制结构

-2.1 提纲

--LinuxCPP0201

-2.2 结构化程序设计基础

--LinuxCPP0202

-2.3 布尔数据

--LinuxCPP0203

-2.4 分支结构

--LinuxCPP0204

-2.5 break语句

--LinuxCPP0205

-2.6 循环结构

--LinuxCPP0206

-2.7 编程实践

--LinuxCPP0207

-第二讲 程序控制结构--编程实践提交入口

第三讲 函数

-3.1 提纲

--LinuxCPP0301

-3.2 函数声明、调用与定义

--LinuxCPP0302

-3.3 函数调用栈框架

--LinuxCPP0303

-3.4 编程实践

--LinuxCPP0304

-第三讲 函数--编程实践提交入口

第四讲 算法

-4.1 提纲

--LinuxCPP0401

-4.2 算法概念与特征

--LinuxCPP0402

-4.3 算法描述

--LinuxCPP0403

-4.4 算法设计与实现

--LinuxCPP0404

-4.5 递归算法(一)

--LinuxCPP0405

-4.6 递归算法(二)

--LinuxCPP0406

-4.7 容错与计算复杂度

--LinuxCPP0407

-4.8 编程实践

--LinuxCPP0408

-第四讲 算法--编程实践提交入口

第五讲 程序组织与开发方法

-5.1 提纲

--LinuxCPP0501

-5.2 库与接口

--LinuxCPP0502

-5.3 随机数库(一)

--LinuxCPP0503

-5.4 随机数库(二)

--LinuxCPP0504

-5.5 作用域与生存期

--LinuxCPP0505

-5.6 典型软件开发流程(一)

--LinuxCPP0506

-5.7 典型软件开发流程(二)

--LinuxCPP0507

-5.8 编程实践

--LinuxCPP0508

-第五讲 程序组织与开发方法--编程实践提交入口

第六讲 复合数据类型

-6.1 提纲

--LinuxCPP0601

-6.2 字符

--LinuxCPP0602

-6.3 数组(一)

--LinuxCPP0603

-6.4 数组(二)

--LinuxCPP0604

-6.5 结构体

--LinuxCPP0605

-6.6 编程实践

--LinuxCPP0606

-第六讲 复合数据类型--编程实践提交入口

第七讲 指针与引用

-7.1 提纲

--LinuxCPP0701

-7.2 指针基本概念

--LinuxCPP0702

-7.3 指针与函数

--LinuxCPP0703

-7.4 指针与复合数据类型(一)

--LinuxCPP0704

-7.5 指针与复合数据类型(二)

--LinuxCPP0705

-7.6 字符串

--LinuxCPP0706

-7.7 动态存储管理(一)

--LinuxCPP0707

-7.8 动态存储管理(二)

--LinuxCPP0708

-7.9 引用

--LinuxCPP0709

-7.10 编程实践

--LinuxCPP0710

-第七讲 指针与引用--编程实践提交入口

第八讲 链表与程序抽象

-8.1 提纲

--LinuxCPP0801

-8.2 数据抽象(一)

--LinuxCPP0802

-8.3 数据抽象(二)

--LinuxCPP0803

-8.4 链表(一)

--LinuxCPP0804

-8.5 链表(二)

--LinuxCPP0805

-8.6 链表(三)

--LinuxCPP0806

-8.7 链表(四)

--LinuxCPP0807

-8.8 函数指针(一)

--LinuxCPP0808

-8.9 函数指针(二)

--LinuxCPP0809

-8.10 抽象链表(一)

--LinuxCPP0810

-8.11 抽象链表(二)

--LinuxCPP0811

-8.12 编程实践

--LinuxCPP0812

-第八讲 链表与程序抽象--编程实践提交入口

第九讲 类与对象

-9.1 提纲

--LinuxCPP0901

-9.2 程序抽象与面向对象

--LinuxCPP0902

-9.3 类类型

--LinuxCPP0903

-9.4 对象(一)

--LinuxCPP0904

-9.5 对象(二)

--LinuxCPP0905

-9.6 类与对象的成员(一)

--LinuxCPP0906

-9.7 类与对象的成员(二)

--LinuxCPP0907

-9.8 类与对象的成员(三)

--LinuxCPP0908

-9.9 继承(一)

--LinuxCPP0909

-9.10 继承(二)

--LinuxCPP0910

-9.11 继承(三)

--LinuxCPP0911

-9.12 多态(一)

--LinuxCPP0912

-9.13 多态(二)

--LinuxCPP0913

-9.14 编程实践

--LinuxCPP0914

-第九讲 类与对象--编程实践提交入口

第十讲 操作符重载

-10.1 提纲

--LinuxCPP1001

-10.2 四则运算符重载(一)

--LinuxCPP1002

-10.3 四则运算符重载(二)

--LinuxCPP1003

-10.4 关系与下标操作符重载

--LinuxCPP1004

-10.5 赋值操作符重载(一)

--LinuxCPP1005

-10.6 赋值操作符重载(二)

--LinuxCPP1006

-10.7 赋值操作符重载(三)

--LinuxCPP1007

-10.8 赋值操作符重载(四)

--LinuxCPP1008

-10.9 赋值操作符重载(五)

--LinuxCPP1009

-10.10 流操作符重载(一)

--LinuxCPP1010

-10.11 流操作符重载(二)

--LinuxCPP1011

-10.12 流操作符重载(三)

--LinuxCPP1012

-10.13 操作符重载总结

--LinuxCPP1013

-10.14 编程实践

--LinuxCPP1014

-第十讲 操作符重载--编程实践提交入口

第十一讲 泛型编程

-11.1 提纲

--LinuxCPP1101

-11.2 泛型编程概览

--LinuxCPP1102

-11.3 异常处理机制(一)

--LinuxCPP1103

-11.4 异常处理机制(二)

--LinuxCPP1104

-11.5 运行期型式信息(一)

--LinuxCPP1105

-11.6 运行期型式信息(二)

--LinuxCPP1106

-11.7 模板与型式参数化

--LinuxCPP1107

-11.8 题外话:术语翻译

--LinuxCPP1108

-11.9 泛型编程实践(一)

--LinuxCPP1109

-11.10 泛型编程实践(二)

--LinuxCPP1110

-11.11 泛型编程实践(三)

--LinuxCPP1111

-11.12 泛型编程实践(四)

--LinuxCPP1112

-11.13 泛型编程实践(五)

--LinuxCPP1113

-11.14 泛型编程实践(六)

--LinuxCPP1114

-11.15 泛型编程实践(七)

--LinuxCPP1115

-11.16 泛型编程实践(八)

--LinuxCPP1116

-11.17 泛型编程实践(九)

--LinuxCPP1117

-11.18 泛型编程实践(十)

--LinuxCPP1118

-11.19 编程实践

--LinuxCPP1119

-第十一讲 泛型编程--编程实践提交入口

第十二讲 Linux系统编程基础

-12.1 提纲

--LinuxCPP1201

-12.2 程序执行环境(一)

--LinuxCPP1202

-12.3 程序执行环境(二)

--LinuxCPP1203

-12.4 程序执行环境(三)

--LinuxCPP1204

-12.5 程序执行环境(四)

--LinuxCPP1205

-12.6 输入输出(一)

--LinuxCPP1206

-12.7 输入输出(二)

--LinuxCPP1207

-12.8 文件系统

--LinuxCPP1208

-12.9 设备

--LinuxCPP1209

-12.10 库(一)

--LinuxCPP1210

-12.11 库(二)

--LinuxCPP1211

-12.12 makefile文件(一)

--LinuxCPP1212

-12.13 makefile文件(二)

--LinuxCPP1213

-12.14 makefile文件(三)

--LinuxCPP1214

-12.15 编程实践

--LinuxCPP1215

-第十二讲 Linux系统编程基础--编程实践提交入口

第十三讲 进程编程

-13.01 提纲

--LinuxCPP1301

-13.02 进程基本概念

--LinuxCPP1302

-13.03 信号

--LinuxCPP1303

-13.04 进程管理(一)

--LinuxCPP1304

-13.05 进程管理(二)

--LinuxCPP1305

-13.06 进程管理(三)

--LinuxCPP1306

-13.07 进程间通信(一)

--LinuxCPP1307

-13.08 进程间通信(二)

--LinuxCPP1308

-13.09 进程间通信(三)

--LinuxCPP1309

-13.10 进程间通信(四)

--LinuxCPP1310

-13.11 进程池

--LinuxCPP1311

-13.12 编程实践

--LinuxCPP1312

-第十三讲 进程编程--编程实践提交入口

第十四讲 线程编程

-14.1 提纲

--LinuxCPP1401

-14.2 线程基本概念

--LinuxCPP1402

-14.3 线程管理(一)

--LinuxCPP1403

-14.4 线程管理(二)

--LinuxCPP1404

-14.5 线程管理(三)

--LinuxCPP1405

-14.6 线程管理(四)

--LinuxCPP1406

-14.7 线程同步机制(一)

--LinuxCPP1407

-14.8 线程同步机制(二)

--LinuxCPP1408

-14.9 C++11线程库(一)

--LinuxCPP1409

-14.10 C++11线程库(二)

--LinuxCPP1410

-14.11 C++11线程库(三)

--LinuxCPP1411

-14.12 C++11线程库(四)

--LinuxCPP1412

-14.13 C++11线程库(五)

--LinuxCPP1413

-14.14 编程实践

--LinuxCPP1414

-第十四讲 线程编程--编程实践提交入口

第十五讲 网络编程

-15.1 提纲

--LinuxCPP1501

-15.2 Internet网络协议

--LinuxCPP1502

-15.3 套接字(一)

--LinuxCPP1503

-15.4 套接字(二)

--LinuxCPP1504

-15.5 编程实践

--LinuxCPP1505

-第十五讲 网络编程--编程实践提交入口

课程文档

-课程PDF文件

LinuxCPP1504笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。