Socket程序设计入门(二)
1.htons()
u_short htons(u_short hostshort);
功能:把一个u_short类型的值从主机字节顺序转换为网络字节顺序
参数:一个以主机字节顺序表示的16位数值
返回:网络字节序表示的16位数值
2.htonl()
u_long htonl(u_long hostlong);
功能:把一个u_long类型的值从主机字节序转换为网络字节序
参数:一个以主机自己序表示的32位数值
返回:网络字节序表示的32位数值
基于UDP的数据发送和接受函数:
3.sendto()
int sendto(SOCKET s, const char FAR * buf, int len,
int flags, const struct sockaddr FAR * to, int tolen);
功能:向一个特定的目的方发送数据
参数:第一个参数是套接字描述符
第二个参数是一个指向缓冲区的指针,该缓冲区包含要发送的数据
第三个参数是缓冲区中要发送的数据的长度,单位是字节(一般情况下,发送端从第二个参数指定的起始地址开始发送这么多个字节)
第四个参数是标示,设置函数调用的行为
第五个参数是目标套接字的地址,是const SOCKADDR *类型
第六个参数是第五个参数指定的地址的长度,单位是字节
返回:当没有错误时,返回实际发送的字节个数,可能比第三个参数len指定的字节数要少
执行失败返回一个SOCKET_ERROR
4.recvfrom()
int recvfrom(SOCKET s, char FAR * buf, int len, int flags,
struct sockaddr FAR * from, int FAR * fromlen);
功能:接受一个数据报信息并保存源地址
参数:第一个参数是准备接受数据报的套接字
第二个参数是一个out类型,指向缓冲区的指针,该缓冲区用来存放接受的数据
第三个参数是缓冲区的长度
第四个参数用来设置函数调用的行为
第五个参数是一个out类型,指向地址结构体的指针,用来保存发送方的地址信息
第六个参数是一个整型指针,是一个in/out类型的参数,在调用前需要给它指定一个初始值,当函数调用之后,会通过这个参数返回一个值,返回值是地址结构的大小
返回:如果没有错误发送,返回实际接受的字节数
注:
sendto()和recvfrom()函数分析
1)char * buf和int len分析
Socket的数据发送和接受传入的参数类型均是char *类型
发送方传入发送的数据的内存起始地址,需要根据发送的数据是否是char *类型需要强制转换为char *类型,随后的参数指明要送的数据长度,需要根据是否发送的是字符串数据进行加1
接收方传入存放接受的数据的缓冲区起始地址,需要根据这段内存起始地址是否为char*类型强制转换为char *类型,随后的参数指明这段内存的大小(字节数)
在sendto()这一端,传入一个const char *类型参数,随后的一个参数指明发送端要发送的字节数
在recvfrom()这一端,传入一个char *类型的参数,随后一个参数指定这个缓冲区的大小(字节数),其中char *参数是out类型,用来存放返回值
实际上我们传入的是一个一段内存的起始地址
当我们传送和接受一个字符串时,传入这个字符串的起始地址,随后的指定其长度的参数应为strlen(字符串)+1
接收端接受字符串时,传入这个字符数组的缓冲区的首地址,随后的参数传入这个缓冲区的大小(字节数)
当我们传送的内存不是char *时,我们获取这段内存的首地址,然后强制转换为char*类型,随后的参数指定这段内存的长度
接收方传入的缓冲区地址不是char *类型时,将这段缓冲区的起始地址强制转换为char*类型作为参数传入
随后的参数指定这段内存的长度(单位是字节)
程序代码如下:
sendto(sockClient, “Hello”, strlen(“Hello”)+1, 0,
(SOCKADDR *)&addrSrv, sizeof(SOCKADDR));
2) SOCKADDR *和int len分析
sendto()和recvfrom()要求的地址结构类型均为SOCKADDR *类型,而二者定义的均是SOCKADDR_IN类型故传入时,需要一个强制类型转换
sendto()传入的地址结构是一个in类型的参数,随后的参数指明这个地址结构的大小
recvfrom()传入的地址结构是一个out类型的参数,作为一个返回值,保存发送方的地址,随后的参数是一个in/out类型的参数,是一个整型的指针,在调用前需要给它指定一个初始值,当函数调用之后,会通过这个参数返回一个值,返回值是地址结构的大小,通常调用前设定它的初始值就是地址结构的大小(sizeof(SOCKADDR))
接受一方的程序代码如下:
SOCKADDR_IN addClient;
int len = sizeof(SOCKADDR_IN);
char recvBuf[100];
recvfrom(sockSrv, recvBuf, 100, 0, (SOCKADDR*)&addrClient, &len);