话题回到“黑社会办公室”的例子,讲概念已经扯得比较远了,不过,这一节我们还得讲概念,不过好在有些程序的例子。如果大家不想翻回去看TcpServer类的原型,我这里直接给出这个头文件的完整源代码:

//Filename: TcpServerClass.hpp

#ifndef TCPSERVERCLASS_HPP_INCLUDED
#define TCPSERVERCLASS_HPP_INCLUDED

#include <unistd.h>
#include <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>

class TcpServer
{
private:
    int listenSock;
    int communicationSock;
    sockaddr_in servAddr;
    sockaddr_in clntAddr;
public:
    TcpServer(int listen_port);
    bool isAccept();
    void handleEcho();
};

#endif // TCPSERVERCLASS_HPP_INCLUDED

我们已经解释了为什么listenSock和communicationSock的类型是int,以及sockaddr_in是什么结构,现在来写这个类的构造函数:

TcpServer::TcpServer(int listen_port)
{
    if ( (listenSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0 ) {
        throw "socket() failed";
    }

memset(&servAddr, 0, sizeof(servAddr));
    servAddr.sin_family = AF_INET;
    servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servAddr.sin_port = htons(listen_port);

if ( bind(listenSock, (sockaddr*)&servAddr, sizeof(servAddr)) < 0 ) {
        throw "bind() failed";
    }

if ( listen(listenSock, 10) < 0 ) {
        throw "listen() failed";
    }
}

好,先看看程序培养一下感觉,我们还得说概念。

数据封装(Data Encapsutation)

我们前面说到了网络分层:链路——网络——传输——应用。数据从应用程序里诞生,传送到互联网上每一层都会进行一次封装:
Data>>Application>>TCP/UDP>>IP>>OS(Driver, Kernel & Physical Address)
我们用socket重点描述的是协议,包括网络协议(IP)和传输协议(TCP/UDP)。
sockaddr重点描述的是地址,包括IP地址和TCP/UDP端口。

socket()函数

我们从TcpServer::TcpServer()函数可以看到,socket和sockaddr的产生是可以相互独立的。socket()的函数原型是:

int socket(int protocolFamily, int type, int protocol);

在Linux中的实现为:

#include <sys/socket.h>

/* Create a new socket of type TYPE in domain DOMAIN, using
   protocol PROTOCOL.  If PROTOCOL is zero, one is chosen automatically.
   Returns a file descriptor for the new socket, or -1 for errors.  */
extern int socket (int __domain, int __type, int __protocol) __THROW;

第一个参数是协议簇(Linux里面叫作域,意思一样的),还是那句话,我们这篇教程用到的就仅仅是一个PF_INET(protocol family : internet),很多时候你会发现人们也经常在这里赋值为AF_INET,事实上,当前,AF_INET就是PF_INET的一个#define,但是,写成PF_INET从语义上会更加严谨。这也就是TCP/IP协议簇中的IP协议(Internet Protocol),网络层的协议。
后面两个参数定义传输层的协议。
第二个参数是传输层协议类型,我们教程里用到的宏,只有两个:SOCK_STREAM(数据流格式)和SOCK_DGRAM(数据报格式);(具体是什么我们以后讨论)
第三个参数是具体的传输层协议。当赋值为0的时候,系统会根据传输层协议类型自动匹配和选择。事实上,当前,匹配SOCK_STREAM的就是TCP协议;而匹配SOCK_DGRAM就是UDP协议。所以,我们指定了第二个参数,第三个就可以简单的设置为0。不过,为了严谨,我们最好还是把具体协议写出来,比如,我们的例子中的TCP协议的宏名称:IPPROTO_TCP。

数据的“地址”

从数据封装的模型,我们可以看到数据是怎么从应用程序传递到互联网的。我们说过,数据的传送是通过socket进行的。但是socket只描述了协议类型。要让数据正确的传送到某个地方,必须添加那个地方的sockaddr地址;同样,要能接受网络上的数据,必须有自己的sockaddr地址。
        可见,在网络上传送的数据包,是socket和sockaddr共同“染指”的结果。他们共同封装和指定了一个数据包的网络协议(IP)和IP地址,传输协议(TCP/UDP)和端口号。

网络字节和本机字节的相互转换

sockaddr结构中的IP地址(sin_addr.s_addr)和端口号(sin_port)将被封装到网络上传送的数据包中,所以,它的结构形式需要保证是网络字节形式。我们这里用到的函数是htons()和htonl(),这些缩写的意思是:
h: host,主机(本机)
n: network,网络
to: to转换
s: short,16位(2字节,常用于端口号)
l: long, 32位(4字节,常用于IP地址)
“反过来”的函数也是存在的ntohs()和ntohl()。

动作与持续行为

本节最后的一个概念可以跟计算机无关。作为动词,有些可以描述动作,有些是描述一重持续的行为状态的(就如同一般动词和be动词一样)。扯到C++来说,我们可以把持续行为封装到函数内部,只留出动作的接口。事实上,构造函数中的bind()和listen()就是这种描述持续状态的行为函数。

socket 编程入门教程(一)TCP server 端:4、构造函数涉及的概念相关推荐

  1. socket 编程入门教程(三)TCP原理:5、TCP的三次握手(three-way handshake)

    socket 编程入门教程(三)TCP原理:5.TCP的三次握手(three-way handshake) 前面3个小节介绍了socket机制对TCP协议三次握手的实现,需要强调的是,与协议独立于实现 ...

  2. socket 编程入门教程(一)TCP server 端:1、建模

    绝大部分关于socket编程的教程总是从socket的概念开始讲起的.要知道,socket的初衷是个庞大的体系,TCP/IP只是这个庞大体系下一个很小的子集,而我们真正能用上的更是这个子集中的一小部分 ...

  3. socket 编程入门教程(一)TCP server 端:7、接收与发送

    现在,我们通过accept()创建了新的socket,也就是我们类中的数据成员communicationSock,现在,我们就可以通过这个socket进行通讯了. TCP通讯模型 在介绍函数之前,我们 ...

  4. socket 编程入门教程(一)TCP server 端:6、创建“通讯 ”嵌套字

    这里的"通讯"加上了引号,是因为实际上所有的socket都有通讯的功能,只是在我们的例子中,之前那个socket只负责listen,而这个socket负责接受信息并echo回去. ...

  5. socket 编程入门教程(一)TCP server端:3、sockaddr与sockaddr_in

    2019独角兽企业重金招聘Python工程师标准>>> 收件人地址 一家化妆品公司将一批新产品的样品,准备发给某学校某个班的女生们免费试用.通常情况下,这件邮包的地址上可以这么写: ...

  6. socket 编程入门教程(一)TCP server 端:5、创建监听嵌套字

    前面一小节,我们已经写出了TcpServer的构造函数.这个函数的实际作用,就是创建了listen socket(监听嵌套字).这一节,我们来具体分析这个创建的过程. socket和sockaddr的 ...

  7. socket 编程入门教程(一)TCP server 端:2、socket与文件描述符

    UNIX中的一切事物都是文件( everything in Unix is a file!) 当我在这篇教程中提到UNIX的时候,其意思专指符合UNIX标准的所谓"正统"UNIX的 ...

  8. socket 编程入门教程(一)TCP server 端:3、sockaddr与sockaddr_in

    收件人地址 一家化妆品公司将一批新产品的样品,准备发给某学校某个班的女生们免费试用.通常情况下,这件邮包的地址上可以这么写: 收件人:全体女生. 地址:A省B市C学校,X级Y班. 但是,如果在描述地址 ...

  9. socket 编程入门教程(三)TCP原理:7、TCP连接的关闭

    2019独角兽企业重金招聘Python工程师标准>>> TCP连接一旦建立,服务器端和客户端就成为了对等关系,任何一方都可以发出关闭握手请求,甚至可以同时发出关闭握手请求.TCP的连 ...

最新文章

  1. 2.2.6 学习率衰减
  2. 如何:重写 ToString 方法(C# 编程指南)
  3. Spring Boot 项目实现热部署
  4. Linux桌面环境介绍以及优缺点分析
  5. Linux 用户篇——用户管理的配置文件
  6. css3动画事件—webkitAnimationEnd
  7. 英国科学家研究用AI预测地震:未来或提前一周预报
  8. 辩论界人机大战:IBM 人工智能和人类辩手几乎平手
  9. intelj idea中除了Find Usage外的另一种查找级联调用的方法
  10. mysql主从分离一致性_数据库主从数据一致性的几种解决方案
  11. VMware12序列号
  12. 用外挂只为“吃鸡”成功?为什么不试试正当手段!
  13. Python实现m3u8下载mp4视频原理及源码
  14. js判断对象上是否含有某个属性
  15. 51单片机 外部中断
  16. 用Visio画UML顺序图
  17. 效率篇-定时任务管理系统,替代crontab
  18. Codeforces 1153C
  19. 华为手机如何更新鸿蒙系统_华为鸿蒙系统可以更新用上啦
  20. 职场新人如何成为沟通高手

热门文章

  1. 如何在excel不同的工作表之间使用数据有效性?
  2. w ndows10电脑配置看哪里,Windows10怎么自动登录?Windows10自动登录的设置方法
  3. n个数里找出前m个数(或者 从10亿个浮点数中找出最大的1万个)
  4. att汇编教程 linux,ATT 汇编语法
  5. android 卡片放大变详情页,ConstraintLayout动画实现布局卡片式滑动放大缩放
  6. php 渐变色,段落每行渐变色文本效果
  7. 云开发数据库VS传统数据库丨云开发101
  8. ORACLE快速遍历树及join基表很大的性能问题
  9. Android_Kotlin 代码学习
  10. Activity的四种启动模式-图文并茂