设为首页 收藏本站
查看: 738|回复: 0

[经验分享] 基于TCP协议的socket编程

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2016-5-25 09:14:38 | 显示全部楼层 |阅读模式

一、什么是socket

socket本身有“插座”的意思,在TCP/IP协议中,“IP地址+TCP或UDP端口号”唯一标识网络通讯中的个进程,“IP地址+端口号”就称为socket。  
在TCP协议中,建立连接的两个进程各自有一个socket来标识,那么这两个socket组成 的socketpair就唯一标识一个连接。

套接字是一种进程间的通信的方法,不同于以往介绍的进程间通信方法的是,它并不局限于同一台计算机的资源,例如文件系统空间,共享内存或者消息队列。套接字可以认为是对管道概念的扩展——一台机器上的进程可以使用套接字与另一台机器上的进程通信。因此客户与服务器可以分散在网络中。同一台机器上的进程间也可以用套接字通信。套接字是一种通信机制,客户/服务器系统既可以在本地单机上运行,也可以在网络中运行。套接字与管道的区别:它明确区分客户与服务器,可以实现将多个客户连接到一个服务器。


二、1.网络字节序:
我们已经知道,内存中的多字节数据相对于内存地址有大端和小端之分,磁盘文件中的多字节数据相对于
文件中的偏移地址也有大端小端之分。网络数据流同样有大端小端之分,发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出,接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存,因此,网络数据流的地址应这样规定:先发出的数据是低地址,后发出的数据是高地址。TCP/IP协议规定,络数据流应采用大端字节序,即低地址高字节。例如UDP段格式中地址0-1是16位的源端口号,如果这个端口号是1000(0x3e8),则地址0是0x03,地址1是0xe8, 也就是先发0x03,再发0xe8,这16位在发送主机的缓冲区中也应该是低地址存0x03,高地址存0xe8。但是,如果发送主机是小端字节序的,这16位被解释成0xe803,而不是1000。因此,发送主机把1000填到发送缓冲区之前需要做字节序的转换。同样地,接收主机如果是小端字节序的, 接到16位的源端口号也要做字节序的转换。如果主机是大端字节序的,发送和接收都不需要做转换。同理,32位的IP地址也要考虑网络字节序和主机字节序的问题。为使络程序具有可移植性,使同样的C代码在大端和小端计算机上编译后都能正常运,可以调 用以下库函数做网络字节序和主机字节序的转换。
wKiom1dET9qhoewKAAA0xa82wp0775.jpg

h表示host,n表示network,l表示32位长整数,s表示16位短整数。例 如htonl表示将32位的长整数从主机字节序转换为网络字节序,例如将IP地址转换后准备发送。如果 主机是小端字节序,这些函数将参数做相应的大小端转换然后返回,如果主机是大端字节序,这些函数不做转换,将参数原封不动地返回。

2.socket地址的数据类型及相关函数

socket API是层抽象的网络编程接,适用于各种底层网络协议,如IPv4、IPv6,以及UNIX Domain Socket。然而,各种网络协议的地址格式并不相同,在这里我们使用sockaddr_in;
wKioL1dEUOqRR27LAABe5pDxq7g384.jpg

3.基于IPv4的socket网络编程,sockaddr_in中的成员struct in_addr sin_addr表示32位的IP地址。但是我们通常用点分十进制的字符串表示IP 地址,以下函数可以在字符串表示 和in_addr表示之间转换。
字符串转in_addr的函数:  
wKioL1dEUQzBZC7eAAAn2vPSip8626.jpg
in_addr转字符串的函数:
wKiom1dEUBmDyFBTAAAZsgi3X7I362.jpg

4.套接字的工作过程(服务器端):

首先,服务器应用程序通过socket系统调用创建一个套接字,它是系统分配给该服务器进程的类似文件描述符的资源,不能与其他进程共享。

wKiom1dEUYGj9WdYAAAU9DGMcLk550.jpg

成功则返回一个文件描述符,失败返回-1;

其次,服务器进程使用bind系统调用给套接字命名。本地套接字的名字是linux文件系统的文件名,一般放在/tmp或者/usr/tmp 目录下。网络套接字的名字是与客户相连接的特定网络有关的服务标识符。此标识符允许linux将进入的针对特定端口号的连接转到正确的服务器进程。

wKioL1dEUq-inmMSAAAUpS3GKmE792.jpg

成功返回0,失败返回-1;


接下来,服务器进程开始等待客户连接到这个命名套接字,调用listen创建一个等待队列以便存放来自客户的进入连接。

wKioL1dEUtDAdF9qAAALB7xBSQM595.jpg

同样成功返回0,失败返回-1


最后,服务器通过accept系统调用来接受客户的连接。此时,会产生一个与原有的命名套接字不同的新套接字,它仅用于与这个特定的客户通信,而命名套接字则被保留下来继续处理来自其他客户的连接。

   wKioL1dEU2yCoJUJAAAmIwkjg6c173.jpg

失败则返回-1;


    5.套接字的工作过程(客户端):调用socket创建一个未命名套接字,将服务器的命名套接字作为一个地址来调用connect与服务器建立连接。一旦建立了连接,就可以像使用底层文件描述符那样来用套接字进行双向的数据通信。

三、如下例子

sever端:

wKiom1dEVvuxT_-RAADOXy5wwVk047.jpg
wKioL1dEV_CBXOacAACT7IS64Z8451.jpg
wKiom1dEVv7CtQkPAACUOBnETu0322.jpg
wKioL1dEV_KitmvcAACiIswelbE170.jpg
wKioL1dEV_OjpOAeAACRs0GPTp8973.jpg
client端:
wKiom1dEVwDSopzGAACuRCE05K4103.jpg
wKioL1dEV_ThC8emAABzeJWLH08015.jpg
运行结果:
其中左边为sever端,右边为client端:例子中的V1,V2,V3是针对单进程,多进程,多线程的。
wKiom1dEVwGhaOqqAAA1Rafnui8270.jpg



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-221508-1-1.html 上篇帖子: CentOS 6.5 下的截图方法 下篇帖子: GeoIP最快捷安装
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表