您的位置:首页 > 理论基础 > 计算机网络

网络编程之:TCP服务器的简单实现

2016-08-08 21:10 316 查看
说到TCP服务器,就不得不提socket编程,我们知道,在TCP/IP协议中,“IP地址+TCP或UDP端口号”唯一标识⽹络通讯中的唯一一个进程,“IP地址+端口号”就称为socket
在TCP协议中,建立连接的两个进程各自有一个socket来标识,那么这两个socket组成 的socket pair就唯一标识一个连接。socket本身有“插座”的意思,因此⽤来描述网络连接的一 对⼀的关 系。 
TCP/IP协议最早在BSD UNIX上实现,为TCP/IP协议设计的应用层编程接口称为socket API。
TCP/IP协议规定:网络数据流规定应采用大端字节序,即低地址存储高位数据,因此网络数据流的地址是由低到高的,此处应包括收取哈发送数据两个过程。
 1.socket数据类型及其相关函数
socket API是一层抽象的⽹网络编程接口,适⽤用于各种底层⽹网络协议,如IPv4、IPv6,以及UNIX Domain Socket。然⽽,各种网络协议的地址格式并不相同,如下图所示:
sockaddr数据结构:



可以看到,各种sockaddr的地址结构前16位都是一样的,都表示整个结构体的长度,IPv4、IPv6和UNIX Domain Socket的地 址类型分别定义为常数AF_INET、AF_INET6、AF_UNI,这样,只要取 得某种sockaddr结构体的 ⾸首地址,不需要知道具体是哪种类型的sockaddr结构体,就可以根据地 址类型字段确定结构体中的内容。因此,socket API可以接受各种类型的sockaddr结构体指针做参数,例如bind、accept、connect等函数,这些函数的参数应该设计成void
*类型以便接受各 种类型的指 针,但是sock API的实现早于ANSI C标准化,那时还没有void *类型,因此这些函数的参数都用struct sockaddr *类型表示,在传递参数之前要强制类型转换⼀下。
举个例子:bind(listen_sock,(struct sockaddr*)&local,sizeof(local))
[align=left]
[/align]
[align=left]
[/align]
[align=left]下面是基于TCP协议服务器/客户端的一般流程:[/align]



[align=left][/align]
[align=left]服务器调用socket()---创建套接字、bind()---绑定、listen()---监听, 完成初始化后,调⽤accept()阻塞等待,处于监听端口的状态,客户端调用socket()初始化后,调用connect()发出SYN段并阻塞等待服务器应答,服务器应答一个SYN-ACK段,客户端收到后从connect()返回,同时应答一个ACK段,服务器收到后从accept()返回。[/align]
[align=left]
[/align]
数据传输的过程: 建立连接后,TCP协议提供全双工的通信服务,但是一般的客户端/服务器程序的流程是由客户端主动发起请求,服务器被动处理请求,一问一答的⽅方式。因此,服务器accept()返回后立刻调用read(),读socket就像读管道一样,如果没有数据到达就阻塞等待,这时客户端调用write()发送请求给服务器,服务器收到后从read()返回,对客户端的请求进行处理,在此
期间客户端调用read()阻塞等待服务器的应答,服务器调用write()将处理结果发回给客户端,再次调⽤用read()阻塞 等待下一条请求,客户端收到后从read()返回,发送下一条请求,如此循环下去。 
[align=left]如果客户端没有更多的请求了,就调用close() 关闭连接,就像写端关闭的管道⼀样,服务器 的 read()返回0,这样服务器就知道客户端关闭了连接,也调⽤用close()关闭连接。注意,任何⼀方close()后,连接的两个传输⽅方向都关闭,不能再发送数据了。如果⼀方调用shutdown() 则连接处于半关闭状态,仍可接收对⽅方发来的数据。[/align]
[align=left]
[/align]
[align=left]下面就来看一下这个服务器和客户端是如何实现的:[/align]
[align=left]首先来到目录下创建server.c和client.c两个文件,在编写一下Makefile文件,然后正式编写server.c:[/align]





 






[align=left] [/align]
[align=left]以上就是server的编写,下面是client 的编写:[/align]







[align=left]
[/align]
[align=left]好了,现在服务器和客户端已将编写好了,我们来测试一下:[/align]

我们在另一个终端进入到目标目录里运行client,并输入文字:



[align=left]然后来看看客户端是否可以收到client发过来的消息:[/align]



[align=left]server已经成功收到了消息,并且TCP服务器只能被动的接受处理client发起的请求,所以只能是server接受client发来的消息,server并不能给client发消息。[/align]
[align=left]好啦,这就是我编写的简单的TCP服务器/客户端啦,希望各种小伙伴们指出问题,共同学习~
[/align]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息