基于TCP协议的网络通信(socket编程)
Posted Xiao__Tian__
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于TCP协议的网络通信(socket编程)相关的知识,希望对你有一定的参考价值。
★网络通信的本质其实也是一种进程间通信,只不过是跨网络的数据通信,与本地的多
个进程间的通信稍有不同,但是其原理都是一样的。
▲在TCP/IP协议中,“IP地址+端口号(TCP或UDP)”可以唯一标识网络通信中的一个进程,这就是socket套接
字。在该协议中,建立连接的两个进程各自有一个socket来标识,所以这两个socket组成的socket pair就可以用来唯
一标识一个连接,用以描述网络连接中一对一的关系。
▲在此之前,先来谈谈网络字节序的有关概念,网络字节序的概念是由机器的大小端存储方式提出的,关于大小端这
里不作过多描述。众所周知,内存中的数据相对于内存地址存在大小端之分,磁盘中的数据相对于文件中的偏移地址
也是存在大小端之分的。网络数据流亦是如此,发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出,
接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存。简单来说,其规则就
是:按照从低地址到高地址的顺序依次发出。在TCP/IP协议中规定了网络数据流统一采用大端字节序(低地址存放高
字节数据),如果主机本身就是大端字节序,发送和接收都不需做任何转换,若是小端字节序,则需要进行字节序的
转换。
对于网络字节序和主机字节序间的转换,系统库函数有以下调用接口函数:
注:h表示host,n表示network,l表示32位长整数,s表示16位短整数。例如htonl表示将32位的长整数从主机字节序转换为网络字
节序,例如将IP地址转换后准备发送。如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回,如果主机是大端字节序,
这些函数不做转换,将参数原封不动地返回。
★socket地址数据类型:
▲关于sockaddr_in结构体的定义。
▲关于IPv4和IPv6的地址格式的结构体定义。
注:IPv4和IPv6的地址格式定义在netinet/in.h中,IPv4地址用sockaddr_in结构体表示,包括16位端口号和32位IP地址,IPv6地址
用sockaddr_in6结构体表示,包括16位端口号、128位IP地址和一些控制字段。UNIX Domain Socket的地址格式定义在
sys/un.h中,用sockaddr_un结构体表示。各种socket地址结构体的开头都是相同的,前16位表示整个结构体的长度(并不是所有
UNIX的实现都有长度字段,如Linux就没有),后16位表示地址类型。IPv4、IPv6和UNIX Domain Socket的地址类型分别定义为常
数AF_INET、AF_INET6、AF_UNIX。这样,只要取得某种sockaddr结构体的首地址,不需要知道具体是哪种类型的sockaddr结构
体,就可以根据地址类型字段确定结构体中的内容。
★基于TCP协议下网络数据通信的套接字编程中主要运用到以下3个函数:
1.socket函数:用于套接字的创建
注:其中参数domain是协议类型,在这里选取IPv4版本的地址格式,所以domain的实参为AF_INET。参数types是服务类型,在
这里应为数据流的形式,所以其实参为SOCKET_STREAM。参数protocol为对应的协议,由前两个参数决定,一旦domain和
types确定,该值也就相应确定了,所以在此并不关心其具体的传参,为零即可。可以看到,其返回值若创建成功则返回一个文件描
述符;若失败则返回-1。
2.bind函数:用于套接字相应信息的绑定
注:其中参数sockfd为socket函数创建的套接字。参数*addr是一个结构体,其中包括了协议类型,IP地址以及端口号的相关信息
的定义。参数addrlen是定义的结构体*addr的大小。其返回值若绑定成功,则返回0;若失败,则返回-1。
3.listen函数:用于监听远端的连接请求
注:其中参数sockfd是由socket函数创建的套接字。参数backlog是请求连接时阻塞队列中进程的上限数。其返回值若成功监听,
则返回0;若失败,则返回-1。
▲相关代码:
1.Server端
2.Client端
3.Makefile自动化编译
检测:
启动运行server端(注意启动server端需指定IP地址及端口号)后,重新打开一个终端窗口,执行netstat -nltp命令,可以查看当
前连接的服务进程。可以看到有一个协议类型为tcp,IP地址为127.0.0.1,端口号为8080的服务进程,且处于监听状态。
运行结果:
以上是关于基于TCP协议的网络通信(socket编程)的主要内容,如果未能解决你的问题,请参考以下文章