实验 6. Linux Socket 编程实验
1、实验目的: (1) 了解 TCP/IP 协议;(2) 掌握 socket 编程。2、实验设备:
(1) PC 机的 VMware 虚拟机运行 Ubuntu Linux 系统;(2) 两机对连的网络线;(3) 带网口的测试计算机;(4) WINDOWS“SOCKET TOOL”调试工具。3、实验内容:实现典型客户机/服务器程序中的服务器及客户机。4、实验原理4.1 客户机/服务器工作流程使用TCP协议的客户机/服务器进程的工作过程如下图4.2 Socket 编程相关函数常用的socket函数有:socket,bind,listen,accept,connect,send,recv。1)socket(建立连接)表头文件:#include<sys/types.h>#include<sys/socket.h>定义函数:int socket(int family,int type,int protocol);函数说明:socket()函数用来生成一个套接口描述字,也称为套接字,指定协议簇和套接口。参数:family指定协议族,type指明字节流方式,而protocol一般为0Family的取值范围:AF_LOCALUNIX协议族AF_ROUTE路由套接口AF_INETIPv4协议AF_INET6IPv6协议AF_KEY密钥套接口参数type的取值范围:SOCK_STREAMTCP套接口SOCK_DGRAMUDP套接口SOCK_PACKET支持数据链路访问SOCK_RAM原始套接口返回值:成功返回非负描述字,失败返回负值2)bind(对socket定位)表头文件:#include<sys/types.h>#include<sys/socket.
h>定义函数:Int bind(int sockfd,struct sockaddr * my_addr,int addrlen);函数说明bind()用来设socket编程聊天室基本流程置给参数sockfd的socket一个名称。此名称由参数my_addr指向一sockaddr结构,对于不同的socketdomain定义了一个通用的数据结构structsockaddr{unsignedshortintsa_family;charsa_data[14];};sa_family为调用socket()时的domain参数,即AF_xxxx值。sa_data最多使用14个字符长度。此sockaddr结构会因使用不同的socketdomain而有不同结构定义,例如使用AF_INETdomain,其socketaddr结构定义便为structsocketaddr_in{unsignedshortintsin_family;uint16_tsin_port;structin_addrsin_addr;unsignedcharsin_zero[8];};structin_addr{uint32_ts_addr;};sin_family即为sa_familysin_port为使用的port编号sin_addr.s_addr为IP地址sin_zero未使用。参数socket为套接字,my_addr是一个指向特定协议地址结构的指针,addrlen为sockaddr的结构长度。返回值成功则返回0,失败返回-1,错误原因存于errno中。错误代码EBADF参数sockfd非合法socket处理代码。EACCESS权限不足ENOTSOCK参数sockfd为一文件描述词,非socket。3)listen(等待连接)表头文件:#include<sys/socket.h>定义函数:Int listen(ints,intbacklog);函数说明:listen()用来等待参数s的socket连线。参数backlog指定同时能处理的最大连接要求,如果连接数目达此上限则client端将收到ECONNREFUSED的错
误。Listen()并未开始接收连线,只是设置socket为listen模式,真正接收client端连线的是accept()。通常listen()会在socket(),bind()之后调用,接着才调用accept()。返回值成功则返回0,失败返回-1,错误原因存于errno附加说明listen()只适用SOCK_STREAM或SOCK_SEQPACKET的socket类型。如果socket为AF_INET则参数backlog最大值可设至128。错误代码EBADF参数sockfd非合法socket处理代码EACCESS权限不足EOPNOTSUPP指定的socket并未支援listen模式。4)accept表头文件:#include<sys/types.h>#include<sys/socket.h>定义函数:Int accept(int s,struct sockaddr * addr,int * addrlen);函数说明accept()用来接受参数s的socket连线。参数s的socket必需先经bind()、listen()函数处理过,当有连线进来时accept()会返回一个新的socket处理代码,往后的数据传送与读取就是经由新的socket处理,而原来参数s的socket能继续使用accept()来接受新的连线要求。连线成功时,参数addr所指的结构会被系统填入远程主机的地址数据,参数addrlen为scokaddr的结构长度。关于结构sockaddr的定义请参考bind()。返回值成功则返回新的socket处理代码,失败返回-1,错误原因存于errno中。错误代码EBADF参数s非合法socket处理代码。EFAULT参数addr指针指向无法存取的内存空间。ENOTSOCK参数s为一文件描述词,非socket。EOPNOTSUPP指定的socket并非SOCK_STREAM。EPERM防火
墙拒绝此连线。ENOBUFS系统的缓冲内存不足。ENOMEM核心内存不足。5)connect(建立socket连线)表头文件:#include<sys/types.h>#include<sys/socket.h>定义函数:Int connect(int sockfd,struct sockaddr * serv_addr,int addrlen);函数说明connect()用来将参数sockfd的socket连至参数serv_addr指定的网络地址。结构sockaddr请参考bind()。参数addrlen为sockaddr的结构长度。返回值成功则返回0,失败返回-1,错误原因存于errno中。错误代码EBADF参数sockfd非合法socket处理代码EFAULT参数serv_addr指针指向无法存取的内存空间ENOTSOCK参数sockfd为一文件描述词,非socket。EISCONN参数sockfd的socket已是连线状态ECONNREFUSED连线要求被server端拒绝。ETIMEDOUT企图连线的操作超过限定时间仍未有响应。ENETUNREACH无法传送数据包至指定的主机。EAFNOSUPPORTsockaddr结构的sa_family不正确。EALREADYsocket为不可阻断且先前的连线操作还未完成。6)send()和recv()这两个函数用于面向连接的socket上进行数据传输。函数定义:Int send(int sockfd,const void * msg,int len,int flags);参数:Sockfd是你想用来传输数据的socket描述符;msg是一个指向要发送数据的指针;Len是以字节为单位的数据的长度;flags一般情况下置为0(关于该参数的用法可参照man手册)。返回值:send()函数返回实际上发送出的字节数,可能会少于你希望发送的数据。在程序中应该将send()的返回值与欲
发送的字节数进行比较。当send()返回值与len不匹配时,应该对这种情况进行处理。char*msg="Hello!";intlen,bytes_sent;......len=strlen(msg);bytes_sent=send(sockfd,msg,len,0);......函数定义:int recv(int sockfd,void * buf,int len,unsigned int flags);参数:sockfd是接受数据的socket描述符;buf是存放接收数据的缓冲区;len是缓冲的长度。Flags也被置为0。返回值:Recv()返回实际上接收的字节数,当出现错误时,返回-1并置相应的errno值。sendto()和recvfrom()用于在无连接的数据报socket方式下进行数据传输。由于本地socket并没有与远端机器建立连接,所以在发送数据时应指明目的地址。5、编译及运行(1) 连接 PC 机和中央网关板的串口线;(2) 打开 PC 机的超级终端,设置“115200,8,n,1”;(3) 连接 PC 机和中央网关板的网络线;(4) 设置 PC 机 IP 地址到”192.168.0.200”;(5) 给中央网关板加电;(6) 使用 arm-linux-gcc 编译文件 socketclient.c 为 socketclient;(7) 将 socketclient 使用 FTP 下载到中央网关板,修改运行权限 chmod +xsocketclient;(8) 运行 Windows 下 sockettool 调试工具,建立 TCP Server,端口 1002;(9) 运行编译后的程序:./socketclient “192.168.0.200” 1002;6、实验现象Socketclient 将连接到 server,输入的数据将在 server 端显示出来。7、附录7.1 计算机网络体系结构模式所有的网络通信方式分为两种:线路交换和包交换。所谓的线路交换,就是指再传输时在发送端和接收端之间建立一个特定的线路连接,数据就可以在这条线路上
传输。电话是采用的这种方式。计算机网络则采用的是包交换,数据的发送端将要传输的数据分割成块,而每个块经过适当的处理后形成一个数据包,包中有接收端的地址等必要信息,每个包单独传输。包中的数据并不是限定死的,只要保证数据的正确传输即可,具体应该定义哪些信息,则与使用的协议有关。(1) OSI 标准OSI标准是开放系统互联标准(OpenSystermInterconnection)即我们通常所说的网络互联的七层框架,他是1977年国际标准化组织提出的一种参考模型。值得注意的是,OSI并没有提供一个可以实现的方法,它不是一个标准而只是一个制定标准时使用的概念性的框架,更不是一个网络协议。1)、物理层(PhysicalLayer):主要功能为定义了网络的物理结构,传输的电磁标准,Bit流的编码及网络的时间原则,如分时复用及分频复用。决定了网络连接类型(端到端或多端连接)及物理拓扑结构。说的通俗一些,这一层主要负责实际的信号传输。2)、链路层(DataLinkReview):在两个主机上建立数据链路连接,向物理层传输数据信号,并对信号进行处理使之无差错并合理的传输。3)、网络层(NetworkLayer):主要负责路由,选择合适的路径,进行阻塞控制等功能。4)、传输层(TransferLayer):最关键的一层,向拥护提供可靠的端到端(End-to-End)服务,它屏蔽了下层的数据通信细节,让用户及应用程序不需要考虑实际的通信方法。5)、会话层(SessionLayer):主要负责两个会话进程之间的通信,即两个会话层实体之间的信息交换,管理
数据的交换。6)、表示层(PresentationLayer):处理通信信号的表示方法,进行不同的格式之间的翻译,并负责数据的加密解密,数据的压缩与恢复。7)、应用层(ApplicationLayer):保持应用程序之间建立连接所需要的数据记录,为用户服务。在工作中,每一层会给上一层传输来的数据加上一个信息头(header),然后向下层发出,然后通过物理介质传输到对方主机,对方主机每一层再对数据进行处理,把信息头取掉,最后还原成实际的数据。本质上,主机的通信是层与层之间的通信,而在物理上是从上向下最后通过物理信道到对方主机再从下向上传输。TCP/IP协议在实际应用中,最重要的是TCP/IP(TransportControlProtocol/InternetProtocol)协议,它是目前最流行的商业化的协议,相对于OSI,它是当前的工业标准或“事实的标准”,在1974年由Kahn提出的。它分为四个层次(从高到低):应用层(与OSI的应用层对应),传输层(与OSI的传输层对应),互联层(与OSI的网络层对应),主机-网络层(与OSI的数据链路层和物理层对应)。7.2 客户机与服务器TCP/IP允许程序员在两个应用程序之间建立通信并来回传递数据,提供一种对等通信,这种对等应用程序可以在同一台机器上,也可以在不同的机器上运行。尽管TCP/IP指明了数据是如何在一对正在通信的应用程序间传递的,但是他并没有规定对等的应用程序在什么时间进行交互以及为什么要进行交互,也没有规定程序员在一个分布式环境下应该如何组织这些应用程序。实践中,有一种组织的方法在使用TCP/IP中占据着主
要地位,现在网络上的绝大多数的通信应用程序都使用这种机制。客户机/服务器模式要求每个应用程序应有两部分组成:一个部分负责启动通信,另一个部分负责对他进行应答。他们通常运行在不同的主机上,分别被称为客户机和服务器。服务器是指能在网络上可提供服务的任何程序;客户机是指用户为了得到某种服务所需要运行的应用程序。一个服务器接受网络上客户机的请求,完成服务后将结果返回给客户机。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论