套接字编程

       套接字(Socket)是用来实现主机与主机通信的一个接口,它屏蔽了底层协议,让用户能够实现各种类型的通信操作,实验室是网络通信中应用程序对应的进程与网络协议之间的接口,如下图:

 

       最初,套接字由加利福尼亚大学伯克利分校开发的,他们是为了在Unix下实现TCP/IP协议,而开发了这样一个编程接口,方便调用网络操作,实际就是一套应用程序接口(API),此API称为Socket,现在Socket几乎是TCP/IP网络标准的API,很多基于TCP/IP的网络应用程序都是基于Socket编写的。

1.为什么要使用Socket?

     应用层通过传输层进行数据通信时,TCP和UDP会同时遇到同时为多个应用程序进程提供并发服务的问题,多个TCP连接或多个应用程序进程可能需要通过同一个TCP协议端口传输数据,为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了一个Socket接口,区分不同应用程序进程间的网络通信和连接,套接字位于协议之上,屏蔽了不同网络协议之间的差异。

2.关于套接字

生成套接字,主要有三个参数:通信的目的IP地址、使用的传输层协议(TCP或UDP)和使用的端口号。将这三个参数结合起来,与一个Socket绑定,应用层就可以和传输层通过Socket接口,区分来自不同应用程序进程或网络连接的通信,实现数据连接的并发服务。

常用的套接字有三种:流(Stream)套接字、数据报(Datagram)套接字、原始(Raw)套接字。

流套接字:提供可靠的双向顺序数据流,可保证数据在传输过程中不会丢失、破坏或重复出现。流套接字是通过INET地址族的TCP实现,它提供了双向、有序、无重复的及无记录边界的数据流服务,它是面向连接的,在发送数据前,双方必须建立数据传输链路,同时还必须对传输的数据进行验证,确保数据的准确性。

数据报套接字:也提供双向的数据传输,但并不对数据的传输进行担保,即数据可能会以错误的顺序传递,甚至丢失或破坏,这种类型的套接字是通过INET地址族的UDP协议实现的,它是面向无连接的,也支持双向的数据流,但不保证数据的准确性,但保留了记录边界,并不保证接收端是否在侦听,数据报套接字传输效率比较高。

原始套接字:可以让进程直接访问底层协议,例如:可以在某个以太网设备上打开原始套接字,然后获取原始的IP数据传输信息。原始套接字可以构造原始的IP数据报文,而前面的两种套接字只能接收到用户数据,因此可以用原始套接字对网络数据进行操作,例如可以接收原始IP报文分析数据内容,很多嗅探器就是用此实现的。还可以利用原始IP报文进行构造网络数据包,然后发送到网络上,网络端口扫描就是利用此来做的,所以原始套接字用在网络安全编程领域比较广泛。
3.套接字基本操作

(1).创建套接字:SOCKET socket(int af,int type,int protocol) 其中返回值是一个SOCKET类型,其实就是一个整数,表示套接字句柄

           af:协议的地址的地址族,IPv4对应的是AF_INET,也是使用最多的类型;

           type:协议的套接字类型,可以是SOCKET_STREAM(使用流套接字)、SOCKET_DGRM(使用的是数据报套接字)等

          protocol:使用的协议类型,如面向连接的是IPPROTO_TCP,面向无连接的是IPPROTO_UDP

(2)绑定套接字:int bind();

(3)监听套接字:int listen();

(4)接收套接字:SOCKET accept();

(5)链接套接字:int connect();

(6)发送数据:int send()(面向连接)/int sendto()(面向无连接)

(7)接收数据:int recv()(面向连接)/int revcfrom()(面向无连接)

(8)关闭套接字:int closesocket()

4.服务类型

(1)面向连接

        服务器端执行步骤:

       1)使用函数WSAStartup()初始化套接字;

       2)调用函数Socket()构造一个套接字;

       3)用函数bind()进行绑定;

       4)用函数listen()进行监听;

       5)用函数accept()接收客户端的连接,此时服务器阻塞,直到有客户端连接服务器才返回,并且创建一个新的套接字,用来传输数据;

       6)在新的套接字上使用rec()函数接收数据;也可以调用send()发送数据,注意,此时所有的操作都是在新的套接字上;

       7)在使用完套接字传送数据后,可以调用函数closesocket()来关闭套接字,释放所有的资源;

       8)最后调用函数WSACleanup()释放WinSock

       客户端执行步骤:

       1)使用函数WSAStartup()初始化套接字;

       2)调用函数socket()构造一个套接字;

       3)调用函数connect()来连接服务器;

       4)连接服务器成功后,可以用函数send()发送数据,也可以用函数revc()接收数据;

       5)数据传送完毕后,使用closesocket()来关闭套接字;

       6)使用WSACleanup()释放Winsock;

(2)面向无连接

        服务器端的执行顺序:

       1)使用函数WSAStartup()初始化套接字;

       2)调用函数socket()构造一个套接字;

       3)调用函数recvfrom()接收数据,也可以使用函数sendto()发送数据,注意,此时再调用recvfrom()函数之后,它就阻塞在那里,等待客户端发送数据,然后才能返回;

       4)等待数据传输完毕,关闭套接字;

       5)最后使用WSACleanup()释放Winsock。

       客户端的执行顺序:

       1)使用函数WSAStartup()初始化套接字;

       2)调用函数socket()构造一个套接字;

       3)然后使用bind()进行绑定;

       4)使用函数sendto()发送数据,也可使用recvfrom()接收数据,注:此时不需要用connect()函数与服务器进行连接,因为是无链接。

       5)等待数据传输完毕,关闭套接字;

       6)最后使用WSACleanup()释放Winsock。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值