socket 编程入门教程(一)TCP server 端:6、创建“通讯 ”嵌套字
这里的“通讯”加上了引号,是因为实际上所有的socket都有通讯的功能,只是在我们的例子中,之前那个socket只负责listen,而这个socket负责接受信息并echo回去。
我们现看看这个函数:
{
unsigned int clntAddrLen = sizeof(clntAddr);
if ( (communicationSock = accept(listenSock, (sockaddr*)&clntAddr, &clntAddrLen)) < 0 ) {
return false;
} else {
std::cout << "Client(IP: " << inet_ntoa(clntAddr.sin_addr) << ") connected.\n";
return true;
}
}
用accept()创建新的socket
在我们的例子中,communicationSock实际上是用函数accept()创建的。
在Linux中的实现为:
When a connection arrives, open a new socket to communicate with it,
set *ADDR (which is *ADDR_LEN bytes long) to the address of the connecting
peer and *ADDR_LEN to the address's actual length, and return the
new socket's descriptor, or -1 for errors.
This function is a cancellation point and therefore not marked with
__THROW. */
extern int accept (int __fd, __SOCKADDR_ARG __addr,
socklen_t *__restrict __addr_len);
这个函数实际上起着构造socket作用的仅仅只有第一个参数(另外还有一个不在这个函数内表现出来的因素,后面会讨论到),后面两个指针都有副作用,在socket创建后,会将客户端sockaddr的数据以及结构体的大小传回。
当程序调用accept()的时候,程序有可能就停下来等accept()的结果。这就是我们前一小节说到的block(阻塞)。这如同我们调用std::cin的时候系统会等待输入直到回车一样。accept()是一个有可能引起block的函数。请注意我说的是“有可能”,这是因为accept()的block与否实际上决定与第一个参数socket的属性。这个文件描述符如果是block的,accept()就block,否则就不block。默认情况下,socket的属性是“可读可写”,并且,是阻塞的。所以,我们不修改socket属性的时候,accept()是阻塞的。
accept()的另一面connect()
accept()只是在server端被动的等待,它所响应的,是client端connect()函数:
虽然我们这里不打算详细说明这个client端的函数,但是我们可以看出来,这个函数与之前我们介绍的bind()有几分相似,特别在Linux的实现中:
For connectionless socket types, just set the default address to send to
and the only address from which to accept transmissions.
Return 0 on success, -1 for errors.
This function is a cancellation point and therefore not marked with
__THROW. */
extern int connect (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len);
connect() 也使用了const的sockaddr,只不过是远程电脑上的而非bind()的本机。
accept()在server端表面上是通过listen socket创建了新的socket,实际上,这种行为是在接受对方客户机程序中connect()函数的请求后发生的。综合起看,被创建的新socket实际上包含了listen socket的信息以及客户端connect()请求中所包含的信息——客户端的sockaddr地址。
新socket与sockaddr的关系
accept()创建的新socket(我们例子中的communicationSock,这里我们简单用newSock来带指)首先包含了listen socket的信息,所以,newSock具有本机sockaddr的信息;其次,因为它响应于client端connect()函数的请求,所以,它还包含了clinet端sockaddr的信息。
我们说过,stream流形式的TCP协议实际上是建立起一个“可来可去”的通道。用于listen的通道,远程机的目标地址是不确定的;但是newSock却是有指定的本机地址和远程机地址,所以,这个socket,才是我们真正用于TCP“通讯”的socket。
inet_ntoa()
/* Convert Internet number in IN to ASCII representation. The return value
is a pointer to an internal array containing the string. */
extern char *inet_ntoa (struct in_addr __in) __THROW;
对于这个函数,我们可以作为一种,将IP地址,由in_addr结构转换为可读的ASCII形式的固定用法。
socket 编程入门教程(一)TCP server 端:6、创建“通讯 ”嵌套字相关推荐
- socket 编程入门教程(三)TCP原理:5、TCP的三次握手(three-way handshake)
socket 编程入门教程(三)TCP原理:5.TCP的三次握手(three-way handshake) 前面3个小节介绍了socket机制对TCP协议三次握手的实现,需要强调的是,与协议独立于实现 ...
- socket 编程入门教程(一)TCP server 端:1、建模
绝大部分关于socket编程的教程总是从socket的概念开始讲起的.要知道,socket的初衷是个庞大的体系,TCP/IP只是这个庞大体系下一个很小的子集,而我们真正能用上的更是这个子集中的一小部分 ...
- socket 编程入门教程(一)TCP server 端:7、接收与发送
现在,我们通过accept()创建了新的socket,也就是我们类中的数据成员communicationSock,现在,我们就可以通过这个socket进行通讯了. TCP通讯模型 在介绍函数之前,我们 ...
- socket 编程入门教程(一)TCP server 端:5、创建监听嵌套字
前面一小节,我们已经写出了TcpServer的构造函数.这个函数的实际作用,就是创建了listen socket(监听嵌套字).这一节,我们来具体分析这个创建的过程. socket和sockaddr的 ...
- socket 编程入门教程(一)TCP server 端:4、构造函数涉及的概念
话题回到"黑社会办公室"的例子,讲概念已经扯得比较远了,不过,这一节我们还得讲概念,不过好在有些程序的例子.如果大家不想翻回去看TcpServer类的原型,我这里直接给出这个头文件 ...
- socket 编程入门教程(一)TCP server端:3、sockaddr与sockaddr_in
2019独角兽企业重金招聘Python工程师标准>>> 收件人地址 一家化妆品公司将一批新产品的样品,准备发给某学校某个班的女生们免费试用.通常情况下,这件邮包的地址上可以这么写: ...
- socket 编程入门教程(一)TCP server 端:2、socket与文件描述符
UNIX中的一切事物都是文件( everything in Unix is a file!) 当我在这篇教程中提到UNIX的时候,其意思专指符合UNIX标准的所谓"正统"UNIX的 ...
- socket 编程入门教程(一)TCP server 端:3、sockaddr与sockaddr_in
收件人地址 一家化妆品公司将一批新产品的样品,准备发给某学校某个班的女生们免费试用.通常情况下,这件邮包的地址上可以这么写: 收件人:全体女生. 地址:A省B市C学校,X级Y班. 但是,如果在描述地址 ...
- socket 编程入门教程(三)TCP原理:7、TCP连接的关闭
2019独角兽企业重金招聘Python工程师标准>>> TCP连接一旦建立,服务器端和客户端就成为了对等关系,任何一方都可以发出关闭握手请求,甚至可以同时发出关闭握手请求.TCP的连 ...
最新文章
- Ubutun重启网卡
- indexof方法_[ 翻译 ] ES6中数组去重的三种方法
- value proposition canvas
- 牛客网【每日一题】3月27日 数学考试
- 网络无人值守安装linux----kickstart
- 不通过ios审核 安装苹果app php,iOS APP审核被拒的解决之道(2.1)
- pyintaller exe 后 print的内容 怎么体现_使用Github Actions自动化构建exe
- (二)元学习算法MAML简介及代码分析
- Jquery_artDialog对话框弹出
- A1075[PAT JUDGE] 好题
- c语言课程设计参考,c语言课程设计参考
- element-ui的upload 上传组件 照片墙当超过限定图片后隐藏上传按钮
- 教你如何写出完美的论文——5. 做笔记
- 【飞轮储能】基于matlab simulink飞轮储能(永磁同步电机)仿真【含Matlab源码 2421期】
- idea @Autowired 飘红
- iphone计算机历史信息,“领先业界5年!” 苹果iPhone历史回顾
- C 语言printf打印各种数据类型的方法(u8/s8/u16/s16.../u64/double/float)(全)
- 【LaTex的PPT模板集】- (亲测有效)在线PPT模板及其使用方法,overleaf与TeXstudio支持中文方法
- 大数据——Spark GraphX中算法介绍
- C# 获取本地输入法列表,切换中英文输入法
热门文章
- windows彻底删除php,windows如何删除php
- 广西2021普通高考成绩查询,2021广西高考成绩什么时候出
- 移植wpa_supplicant软件与DHCP软件解密WPA/WPA2 加密的无线网络
- phantomJs原理
- LeetCode:204. 计数质数
- mac os x10.9.2 查看进程对应端口
- iOS 直接使用16进制颜色
- Xamarin Mono for VS开发窗体标题(Title)乱码解决方案
- CTabCtrl控件标签的相关设置
- 坑爹的UICollectionView