欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

Visual C++网络编程(黑客)学习笔记七

Visual C++网络编程(黑客)学习笔记七

下面介绍TCP Socket与UDP Socket
Stream(TCP) Socket:提供双向,可靠,有次序,不重复的数据传送。
Datagram(UDP) Socket:虽然提供双向的通信,但没有可靠,有次序,不重复的保证。
一般情况下TCP Socket的数据发送和接受是调用send()和recv()这两个函数来完成的;UDP Socket则调用sendto()和recvfrom()这两个函数。这两对函数调用成功返回发送或接受的数据的长度,失败返回SOCKET_ERROR。
函数原型:
int send(
           SOCKET s,
           const char FAR *buf,
           int len,
           int flags
);
参数解释:
s:指定发送端套接字描述符。
buf:指明一个存放应用程序要发送数据的缓冲区。
len:指明实际要发送的数据的字节数。
flag:一般置0。
不论是客户端还是服务端应用程序都用send函数向TCP连接的另一端发送数据。客户端一般用send向服务器发送请求,服务端一般用send向客户端发送应答。
对于同步Socket的send函数的执行流程,当调用该函数时,send先比较待发送数据的长度(len)和套接字s的发送端缓冲区长度。
如果len>s,函数返回SOCKET_ERROR,发送失败;
如果len<s或者len=s,那么send先检查协议是否正在发送s的发送缓冲区的数据,如果是,那么就等协议把数据发送完,如果协议还没有开始发送s的发送缓冲区中的数据或者s的发送缓冲区中没有数据,那么send就比较s的发送缓冲区的剩余空间和len的大小。如果len>剩余空间,send就一直等待协议把s的的发送缓冲区中的数据发送完;如果len<s的发送缓冲区的剩余空间,send就仅仅把buf中的数据复制到剩余空间里(注意,并不是send把s的发送缓冲区中的数据传到连接的另一端,而是协议传送的,send仅仅是把buf中的数据复制到s的发送缓冲区的剩余空间)。
如果send函数复制数据成功就返回实际复制的字节数;如果send在复制数据时出现错误,那么send就返回SOCKET_ERROR;如果send在等待协议传送数据时网络断开的话,那么send函数也返回SOCKET_ERROR。
send函数把buf中的数据成功复制到s的发送缓冲区的剩余空间后它就返回了,但是此时这些数据并不一定马上被传到连接的另一端。如果协议在后续的传送过程中出现网络错误的话,那么下一个socket函数就会返回SOCKET_ERROR.
函数原型:
int recv(
        SOCKET s,
        char FAR *buf,
        int len,
        int flags
);
参数解释:
s:指定接收端套接字描述符。
buf:指明一个缓冲区,用来存放recv函数收到的数据。
len:指明buf的长度。
flags:一般置0.
不论是客户端还是服务器端应用程序都用recv函数从TCP/IP连接的另一端接受数据。
对于同步Socket的recv函数的执行流程,当应用程序调用recv函数时,recv函数先等待s的发送缓冲区中的数据传输完毕。如果协议在传送s的发送缓冲区中的数据时出现网络错误,那么recv函数返回SOCKET_ERROR;如果s的发送缓冲区中没有数据或者数据被协议成功发送完毕,那么recv先检查套接字s的接收缓冲区,如果s的接收缓冲区中没有数据或者协议正在发送数据,那么recv就一直等待,直到协议把数据发送完毕。
当协议把数据接收完毕,recv函数就把s的接收缓冲区中的数据拷贝到buf中(注意协议接收到的数据可能大于buf的长度,所以在这种情况下需要调用几次recv函数才能把s的接收缓冲区中的数据拷贝完。recv函数仅仅是拷贝数据,真正的接收数据是协议完成的)。
recv函数返回其实际拷贝的字节数,如果recv在拷贝时出错,那么返回SOCKET_ERROR,如果recv在等待协议接收数据时网络中断,那么它返回0.
函数原型:
int send(
         SOCKET s,
         const char *buf,
         int len,
         int flags,
         const struct sockaddr* to,
         int tolen
);
参数解释:
s:指定发送端套接字描述符。
buf:指明一个存放应用程序要发送数据的缓冲区。
len:指明实际要发送的数据的字节数。
flags:一般置0.
to:指向目的地址的指针。
tolen:to的长度。
提示:因为在无连接的情况下,本地socket并没有和远程机器建立连接,所以在发送数据时应指明目的地址,因此sendto比send函数多了两个参数:to表示目的机器的IP和PORT,而tolen一般赋为sizeof(struct sockaddr)。
对于Datagram Socket而言,若是datagram的大小超过限制,则不会传送任何数据,并会传回错误值。对于Stream Socket而言,在Blocking模式下,若是传送系统内的存储空间不够存放这些要传送的数据,send()将会被block住,知道数据传完为止;如果该Socket被设定为Non-Blocking模式,那么将视目前的output buf空间有多少就送出多少数据,并不会被block住.flags的值可设为0或MSG_DONTROUTE及MSG_OOB的组合。
函数原型:
int recvfrom(
        SOCKET s,
        char *buf,
        int     len,
        int     flags,
        struct  sockaddr *from,
        int *fromlen
);
参数解释:
s:指定接收端套接字描述符。
buf:指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据。
len:指明buf的长度。
flags:一般置0.
from:数据包的来源地址。
fromlen:from的长度。
提示:因为在无连接的情况下,本地socket并没有和远程机器建立连接,所以收到UDP数据时,要通过from参数判断来源。

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功