基于UDP的效劳器端和客户端
后面的文章中我们给出了几个TCP的例子,关于UDP而言,只需能了解后面的内容,完成并责难事。
成都创新互联公司专注为客户提供全方位的互联网综合服务,包含不限于成都网站建设、成都网站制作、六盘水网络推广、小程序开发、六盘水网络营销、六盘水企业策划、六盘水品牌公关、搜索引擎seo、人物专访、企业宣传片、企业代运营等,从售前售中售后,我们都将竭诚为您服务,您的肯定,是我们最大的嘉奖;成都创新互联公司为所有大学生创业者提供六盘水建站搭建服务,24小时服务热线:18980820575,官方网址:www.cdcxhl.com
UDP中的效劳器端和客户端没有衔接
UDP不像TCP,无需在衔接形态下交流数据,因而基于UDP的效劳器端和客户端也无需经由衔接进程。也就是说,不用挪用 listen() 和 accept() 函数。UDP中只要创立套接字的进程和数据交流的进程。
UDP效劳器端和客户端均只需1个套接字
TCP中,套接字是一对一的关系。如要向10个客户端供给效劳,那么除了担任监听的套接字外,还需求创立10套接字。但在UDP中,不论是效劳器端照样客户端都只需求1个套接字。之前说明UDP道理的时分举了邮寄包裹的例子,担任邮寄包裹的快递公司可以比方为UDP套接字,只需有1个快递公司,就可以经过它向恣意地址邮寄包裹。异样,只需1个UDP套接字就可以向恣意主机传送数据。
基于UDP的接纳和发送函数
创立好TCP套接字后,传输数据时无需再添加地址信息,由于TCP套接字将坚持与对方套接字的衔接。换言之,TCP套接字晓得目的地址信息。但UDP套接字不会坚持衔接形态,每次传输数据都要添加目的地址信息,这相当于在邮寄包裹前填写收件人地址。
发送数据运用 sendto() 函数:
ssize_t sendto(int sock, void *buf, size_t nbytes, int flags, struct sockaddr *to, socklen_t addrlen); //Linux int sendto(SOCKET sock, const char *buf, int nbytes, int flags, const struct sockadr *to, int addrlen); //Windows
Linux和Windows下的 sendto() 函数相似,下面是具体参数阐明:
sock:用于传输UDP数据的套接字;
buf:保管待传输数据的缓冲区地址;
nbytes:带传输数据的长度(以字节计);
flags:可选项参数,若没有可传递0;
to:存有目的地址信息的 sockaddr 构造体变量的地址;
addrlen:传递给参数 to 的地址值构造体变量的长度。
UDP 发送函数 sendto() 与TCP发送函数 write()/send() 的最大差别在于,sendto() 函数需求向他传递目的地址信息。
接纳数据运用 recvfrom() 函数:
ssize_t recvfrom(int sock, void *buf, size_t nbytes, int flags, struct sockadr *from, socklen_t *addrlen); //Linux int recvfrom(SOCKET sock, char *buf, int nbytes, int flags, const struct sockaddr *from, int *addrlen); //Windows
因为UDP数据的发送端不不定,所以 recvfrom() 函数界说为可接纳发送端信息的方式,详细参数如下:
sock:用于接纳UDP数据的套接字;
buf:保管接纳数据的缓冲区地址;
nbytes:可接纳的最大字节数(不克不及超越buf缓冲区的巨细);
flags:可选项参数,若没有可传递0;
from:存有发送端地址信息的sockaddr构造体变量的地址;
addrlen:保管参数 from 的构造体变量长度的变量地址值。
基于UDP的反响效劳器端/客户端
下面联合之前的内容完成反响客户端。需求留意的是,UDP分歧于TCP,不存在恳求衔接和受理进程,因而在某种意义上无法明白辨别效劳器端和客户端,只是由于其供给效劳而称为效劳器端,愿望列位读者不要曲解。
下面给出Windows下的代码,Linux与此相似,不再赘述。
效劳器端 server.cpp:
#include#include #pragma comment (lib, "ws2_32.lib") //加载 ws2_32.dll #define BUF_SIZE 100 int main(){ WSADATA wsaData; WSAStartup( MAKEWORD(2, 2), &wsaData); //创立套接字 SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0); //绑定套接字 sockaddr_in servAddr; memset(&servAddr, 0, sizeof(servAddr)); //每一个字节都用0填充 servAddr.sin_family = PF_INET; //运用IPv4地址 servAddr.sin_addr.s_addr = htonl(INADDR_ANY); //主动获取IP地址 servAddr.sin_port = htons(1234); //端口 bind(sock, (SOCKADDR*)&servAddr, sizeof(SOCKADDR)); //接纳客户端恳求 SOCKADDR clntAddr; //客户端地址信息 int nSize = sizeof(SOCKADDR); char buffer[BUF_SIZE]; //缓冲区 while(1){ int strLen = recvfrom(sock, buffer, BUF_SIZE, 0, &clntAddr, &nSize); sendto(sock, buffer, strLen, 0, &clntAddr, nSize); } closesocket(sock); WSACleanup(); return 0; }
代码阐明:
1) 第12行代码在创立套接字时,向 socket() 第二个参数传递 SOCK_DGRAM,以指明运用UDP协定。
2) 第18行代码中运用htonl(INADDR_ANY)来主动获取IP地址。
应用常数 INADDR_ANY 主动获取IP地址有一个分明的益处,就是当软件装置到其他效劳器或许效劳器IP地址改动时,不必再更改源码从新编译,也不必在启动软件时手动输出。并且,假如一台盘算机中已分派多个IP地址(例如路由器),那么只需端标语分歧,就可以从分歧的IP地址接纳数据。所以,效劳器中优先思索运用INADDR_ANY;而客户端中除非带有一局部效劳器功用,不然不会采取。
客户端 client.cpp:
#include#include #pragma comment(lib, "ws2_32.lib") //加载 ws2_32.dll #define BUF_SIZE 100 int main(){ //初始化DLL WSADATA wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData); //创立套接字 SOCKET sock = socket(PF_INET, SOCK_DGRAM, 0); //效劳器地址信息 sockaddr_in servAddr; memset(&servAddr, 0, sizeof(servAddr)); //每一个字节都用0填充 servAddr.sin_family = PF_INET; servAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); servAddr.sin_port = htons(1234); //不时获取用户输出并发送给效劳器,然后承受效劳器数据 sockaddr fromAddr; int addrLen = sizeof(fromAddr); while(1){ char buffer[BUF_SIZE] = {0}; printf("Input a string: "); gets(buffer); sendto(sock, buffer, strlen(buffer), 0, (struct sockaddr*)&servAddr, sizeof(servAddr)); int strLen = recvfrom(sock, buffer, BUF_SIZE, 0, &fromAddr, &addrLen); buffer[strLen] = 0; printf("Message form server: %s\n", buffer); } closesocket(sock); WSACleanup(); return 0; }
先运转 server,再运转 client,client 输入后果为:
Input a string: C言语中文网
Message form server: C言语中文网
Input a string: c.biancheng.net Founded in 2012
Message form server: c.biancheng.net Founded in 2012
Input a string:
从代码中可以看出,server.cpp 中没有运用 listen() 函数,client.cpp 中也没有运用 connect() 函数,由于 UDP 不需求衔接。
标题名称:基于UDP的效劳器端和客户端
当前网址:http://scyanting.com/article/gocsgc.html