socket编程——一个简单的样例
从一个简单的使用TCP样例開始socket编程,其基本过程例如以下:
server client
+++++++ ++++++++
创建socket 创建socket
+++++++ ++++++++
| |
| |
| |
+++++++ ++++++++
地址赋值( 地址赋值(
自己的地址) server地址)
+++++++ ++++++++
| |
| |
| |
++++++++ |
用bind绑定 |
socket和地址 |
++++++++ |
| |
| |
| |
+++++++ |
listen |
+++++++ |
| ++++++++++
| <------------------------------ connect server
| ++++++++++
+++++++ |
accept |
+++++++ |
| |
| +++++++++
| recv 和send
| 进行数据处理
| +++++++++
+++++++++ |
用accept得到 |
的socket进行 |
recv 和 send |
+++++++++ |
| |
| |
| |
+++++++++ +++++++++
close socket close socket
+++++++++ +++++++++
依据以上步骤,server端的代码为
client代码为:
如今一个简单的使用tcp的socket通信的样例已经完毕了,这里有几个须要说明的问题
1)头文件:
sys/socket.h 包括了socket相关的函数,如socket,send 和recv, 以及struct sockaddr等
netinet/in.h 包括了地址结构,如struct sockaddr_in
errno.h 包括了errno 和 EINTR
syslog.h 包括了syslog相关的信息,其打印结果在/var/log/messages里面
2)socket地址
对于IPv4来说,其地址用的是struct sockaddr_in,详细结构例如以下
当中sin_len我们一般不关注,也不填(仅仅有在使用routing socket的时候才用到,被内核用来处理各种协议簇的地址结构)。
bind, connect, sendto, 和 sendmsg会把socket地址从程序传递给内核; 而accept, recvfrom, recvmsg, getpeername, 和 getsockname会把地址从内核传递给程序。由于不同协议簇的地址结构是不一样的,所以必需要有一个通用的指针来传递地址,对于ANSI C来说我们一般使用void *,可是socket产生早于ANSI C,所以也就没有使用这个机制,而是使用一个通用的地址结构struct sockaddr来处理的
IPv6的socket地址为struct sockaddr_in6
对于sockaddr-in6来说,我们不能用通用的地址struct sockaddr来存储了,而是产用新的通用地址结构struct sockaddr_storage,这个结构足够大能够存储不论什么系统支持的地址。
几种常见的地址结构
![]()
3) 相关函数的的length
对于从程序传地址给内核的函数(如connect),其长度是一个整型值,告诉内核要copy的地址长度。
对于从内核传递给程序的函数(如accpt),其长度是一个整型指针,是一个value-result參数。有两个目的:一告诉内核地址结构的长度,让内核在copy的时候不要超过这个长度;二返回内核真正copy的长度。
4)字节序
socket相关的函数都是使用网络字节序
5)地址转换函数
inet_aton, inet_ntoa, and inet_addr把IPv4字符串地址转为32位的网络字节序地址
inet_ptonand inet_ntop能够转换IPv4和IPv6的地址
6)listen中的backlog
要知道这个值的含义先用说一下,对于一个listen的socket,有两个队列:一个是incomplete connection队列(只收到SYN);一个是complete connection队列(三次握手完毕)。accept函数就是在complete connection队列中取一个socket。backlog就是指队列的个数,但不行的是各个地方都没有明白定义这个值,没有说明到底代表了哪个队列,或是两个队列之和。一般来说能够
同一时候处理的连接数是backlog的1.5倍,非常多地方都用5.
7) getsockname 和 getpeername
这两个函数能够与socket关联的地址,getsockname 和 getpeername分别得到自己和对端的地址
相关文章
- iOS编程中的音频知识(二):那么多种格式我应该用哪一个?
- 面向切面编程AOP[二](java @EnableAspectJAutoProxy 代码原理)
- Spring实战4—面向切面编程
- 【7013】编程求一个后缀表达式的值
- 编程笔试(解析及代码实现):猴子吃桃。猴子第一天吃了若干个桃子,当即吃了一半,还不解馋,又多吃了一个…的C++、Java、Python、C#等语言代码实现
- 编程笔试(解析及代码实现):序列重排之给一个长度为n的序列A,求找出某种排列方式使得相邻两个数的差值之和最大并求出该最大值
- Qt网络编程的命令模式:把网络命令封装成类
- Java并发编程实战读书笔记5 ---Executor在android中的应用
- 【代码质量】RAII在C++编程中的必要性
- C/C++编程:打印任何容器&&生成随机数组
- Python编程:records库操作SQL查询MySQL数据库
- Python编程:FakeRequests一个对 requests 的包装类
- Python编程:python-attrs模块的简单使用
- 【编程实践】Go Web开发:使用Gin快速实现一个HTTP接口
- LabVIEW编程LabVIEW开发欧姆龙E5CC温控器 例程与相关资料
- LabVIEW编程LabVIEW开发ZL-524 四路模拟量采集模块例程与相关资料
- python基础课程_学习笔记26:编程的乐趣
- C++剪切板编程中遇到的一个问题
- bash编程 将一个目录里所有文件存为一个array 并分割为三等分——利用bash array切片
- 使用 Kitten 编程猫绘制一个魔方