您现在的位置是:首页» windows系统» udp和websocket,socket和tcp udp的联系

udp和websocket,socket和tcp udp的联系

2023-12-05 02:50:34
今天小编为大家分享Windows系统下载、Windows系统教程、windows相关应用程序的文章,希望能够帮助到大家! UDP Server程序\x0d\x0a1、编写UDP Server程序的步骤\x0d\x0a(1)使用socket()来建立一个UDP socket,第二个参数为SOCK_DGRAM

今天小编为大家分享Windows系统下载、Windows系统教程、windows相关应用程序的文章,希望能够帮助到大家!

UDP Server程序\x0d\x0a1、编写UDP Server程序的步骤\x0d\x0a(1)使用socket()来建立一个UDP socket,第二个参数为SOCK_DGRAM。\x0d\x0a(2)初始化sockaddr_in结构的变量,并赋值。sockaddr_in结构定义:\x0d\x0astruct sockaddr_in{\x0d\x0auint8_t sin_len;\x0d\x0asa_family_t sin_family;\x0d\x0ain_port_t sin_port;\x0d\x0astruct in_addr sin_addr;\x0d\x0achar sin_zero[8];\x0d\x0a};\x0d\x0a这里使用“08”作为服务程序的端口,使用“INADDR_ANY”作为绑定的IP地址即任何主机上的地址。\x0d\x0a(3)使用bind()把上面的socket和定义的IP地址和端口绑定。这里检查bind()是否执行成功,如果有错误就退出。这样可以防止服务程序重复运行的问题。\x0d\x0a(4)进入无限循环程序,使用recvfrom()进入等待状态,直到接收到客户程序发送的数据,就处理收到的数据,并向客户程序发送反馈。这里是直接把收到的数据发回给客户程序。\x0d\x0a\x0d\x0a2、udpserv.c程序内容:\x0d\x0a#include \x0d\x0a#include \x0d\x0a#include \x0d\x0a#include \x0d\x0a#include \x0d\x0a#include \x0d\x0a\x0d\x0a#define MAXLINE 80\x0d\x0a#define SERV_PORT 8888\x0d\x0a\x0d\x0avoid do_echo(int sockfd, struct sockaddr*pcliaddr, socklen_t clilen)\x0d\x0a{\x0d\x0aint n;\x0d\x0asocklen_t len;\x0d\x0achar mesg[MAXLINE];\x0d\x0a\x0d\x0afor(;;)\x0d\x0a{\x0d\x0alen= clilen;\x0d\x0a/* waiting for receive data*/\x0d\x0an= recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr,&len);\x0d\x0a/* sent data back to client*/\x0d\x0asendto(sockfd, mesg, n, 0, pcliaddr, len);\x0d\x0a}\x0d\x0a}\x0d\x0a\x0d\x0aint main(void)\x0d\x0a{\x0d\x0aint sockfd;\x0d\x0astruct sockaddr_in servaddr, cliaddr;\x0d\x0a\x0d\x0asockfd= socket(AF_INET, SOCK_DGRAM, 0);/* create a socket*/\x0d\x0a\x0d\x0a/* init servaddr*/\x0d\x0abzero(&servaddr, sizeof(servaddr));\x0d\x0aservaddr.sin_family= AF_INET;\x0d\x0aservaddr.sin_addr.s_addr= htonl(INADDR_ANY);\x0d\x0aservaddr.sin_port= htons(SERV_PORT);\x0d\x0a\x0d\x0a/* bind address and port to socket*/\x0d\x0aif(bind(sockfd,(struct sockaddr*)&servaddr, sizeof(servaddr))==-1)\x0d\x0a{\x0d\x0aperror("bind error");\x0d\x0aexit(1);\x0d\x0a}\x0d\x0a\x0d\x0ado_echo(sockfd,(struct sockaddr*)&cliaddr, sizeof(cliaddr));\x0d\x0a\x0d\x0areturn 0;\x0d\x0a}\x0d\x0a\x0d\x0aUDP Client程序\x0d\x0a1、编写UDP Client程序的步骤\x0d\x0a(1)初始化sockaddr_in结构的变量,并赋值。这里使用“8888”作为连接的服务程序的端口,从命令行参数读取IP地址,并且判断IP地址是否符合要求。\x0d\x0a(2)使用socket()来建立一个UDP socket,第二个参数为SOCK_DGRAM。\x0d\x0a(3)使用connect()来建立与服务程序的连接。与TCP协议不同,UDP的connect()并没有与服务程序三次握手。上面我们说了UDP是非连接的,实际上也可以是连接的。使用连接的UDP,kernel可以直接返回错误信息给用户程序,从而避免由于没有接收到数据而导致调用recvfrom()一直等待下去,看上去好像客户程序没有反应一样。\x0d\x0a(4)向服务程序发送数据,因为使用连接的UDP,所以使用write()来替代sendto()。这里的数据直接从标准输入读取用户输入。\x0d\x0a(5)接收服务程序发回的数据,同样使用read()来替代recvfrom()。\x0d\x0a(6)处理接收到的数据,这里是直接输出到标准输出上。\x0d\x0a\x0d\x0a2、udpclient.c程序内容:\x0d\x0a#include \x0d\x0a#include \x0d\x0a#include \x0d\x0a#include \x0d\x0a#include \x0d\x0a#include \x0d\x0a#include \x0d\x0a#include \x0d\x0a\x0d\x0a#define MAXLINE 80\x0d\x0a#define SERV_PORT 8888\x0d\x0a\x0d\x0avoid do_cli(FILE*fp, int sockfd, struct sockaddr*pservaddr, socklen_t servlen)\x0d\x0a{\x0d\x0aint n;\x0d\x0achar sendline[MAXLINE], recvline[MAXLINE+ 1];\x0d\x0a\x0d\x0a/* connect to server*/\x0d\x0aif(connect(sockfd,(struct sockaddr*)pservaddr, servlen)==-1)\x0d\x0a{\x0d\x0aperror("connect error");\x0d\x0aexit(1);\x0d\x0a}\x0d\x0a\x0d\x0awhile(fgets(sendline, MAXLINE, fp)!= NULL)\x0d\x0a{\x0d\x0a/* read a line and send to server*/\x0d\x0awrite(sockfd, sendline, strlen(sendline));\x0d\x0a/* receive data from server*/\x0d\x0an= read(sockfd, recvline, MAXLINE);\x0d\x0aif(n==-1)\x0d\x0a{\x0d\x0aperror("read error");\x0d\x0aexit(1);\x0d\x0a}\x0d\x0arecvline[n]= 0;/* terminate string*/\x0d\x0afputs(recvline, stdout);\x0d\x0a}\x0d\x0a}\x0d\x0a\x0d\x0aint main(int argc, char**argv)\x0d\x0a{\x0d\x0aint sockfd;\x0d\x0astruct sockaddr_in srvaddr;\x0d\x0a\x0d\x0a/* check args*/\x0d\x0aif(argc!= 2)\x0d\x0a{\x0d\x0aprintf("usage: udpclient\n");\x0d\x0aexit(1);\x0d\x0a}\x0d\x0a\x0d\x0a/* init servaddr*/\x0d\x0abzero(&servaddr, sizeof(servaddr));\x0d\x0aservaddr.sin_family= AF_INET;\x0d\x0aservaddr.sin_port= htons(SERV_PORT);\x0d\x0aif(inet_pton(AF_INET, argv[1],&servaddr.sin_addr)<= 0)\x0d\x0a{\x0d\x0aprintf("[%s] is not a valid IPaddress\n", argv[1]);\x0d\x0aexit(1);\x0d\x0a}\x0d\x0a\x0d\x0asockfd= socket(AF_INET, SOCK_DGRAM, 0);\x0d\x0a\x0d\x0ado_cli(stdin, sockfd,(struct sockaddr*)&servaddr, sizeof(servaddr));\x0d\x0a\x0d\x0areturn 0;\x0d\x0a}\x0d\x0a\x0d\x0a运行例子程序\x0d\x0a1、编译例子程序\x0d\x0a使用如下命令来编译例子程序:\x0d\x0agcc-Wall-o udpserv udpserv.c\x0d\x0agcc-Wall-o udpclient udpclient.c\x0d\x0a编译完成生成了udpserv和udpclient两个可执行程序。\x0d\x0a\x0d\x0a2、运行UDP Server程序\x0d\x0a执行./udpserv&命令来启动服务程序。我们可以使用netstat-ln命令来观察服务程序绑定的IP地址和端口,部分输出信息如下:\x0d\x0aActive Internet connections(only servers)\x0d\x0aProto Recv-Q Send-Q Local Address Foreign Address State\x0d\x0atcp 0 0 0.0.0.0:32768 0.0.0.0:* LISTEN\x0d\x0atcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN\x0d\x0atcp 0 0 0.0.0.0:6000 0.0.0.0:* LISTEN\x0d\x0atcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN\x0d\x0audp 0 0 0.0.0.0:32768 0.0.0.0:*\x0d\x0audp 0 0 0.0.0.0:8888 0.0.0.0:*\x0d\x0audp 0 0 0.0.0.0:111 0.0.0.0:*\x0d\x0audp 0 0 0.0.0.0:882 0.0.0.0:*\x0d\x0a可以看到udp处有“0.0.0.0:8888”的内容,说明服务程序已经正常运行,可以接收主机上任何IP地址且端口为8888的数据。\x0d\x0a如果这时再执行./udpserv&命令,就会看到如下信息:\x0d\x0abind error: Address already in use\x0d\x0a说明已经有一个服务程序在运行了。\x0d\x0a\x0d\x0a3、运行UDP Client程序\x0d\x0a执行./udpclient 127.0.0.1命令来启动客户程序,使用127.0.0.1来连接服务程序,执行效果如下:\x0d\x0aHello, World!\x0d\x0aHello, World!\x0d\x0athis is a test\x0d\x0athis is a test\x0d\x0a^d\x0d\x0a输入的数据都正确从服务程序返回了,按ctrl+d可以结束输入,退出程序。\x0d\x0a如果服务程序没有启动,而执行客户程序,就会看到如下信息:\x0d\x0a$./udpclient 127.0.0.1\x0d\x0atest\x0d\x0aread error: Connection refused\x0d\x0a说明指定的IP地址和端口没有服务程序绑定,客户程序就退出了。这就是使用connect()的好处,注意,这里错误信息是在向服务程序发送数据后收到的,而不是在调用connect()时。如果你使用tcpdump程序来抓包,会发现收到的是ICMP的错误信息。

这是在网上找到的,希望对你有所帮助。

sockets(套接字)编程有三种,流式套接字(SOCK_STREAM),数据报套接字(SOCK_DGRAM),原始套接字(SOCK_RAW);

WINDOWS环境下TCP/UDP编程步骤:

1.基于TCP的socket编程是采用的流式套接字。

在这个程序中,将两个工程添加到一个工作区。要链接一个ws2_32.lib的库文件。

1:加载套接字库,创建套接字(WSAStartup()/socket());

2:绑定套接字到一个IP地址和一个端口上(bind());

3:将套接字设置为监听模式等待连接请求(listen());

4:请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept());

5:用返回的套接字和客户端进行通信(send()/recv());

7:关闭套接字,关闭加载的套接字库(closesocket()/WSACleanup())。

wVersionRequested= MAKEWORD( 1, 1);

err= WSAStartup( wVersionRequested,&wsaData);

if( LOBYTE( wsaData.wVersion)!= 1||

HIBYTE( wsaData.wVersion)!= 1){

SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);

addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);

addrSrv.sin_port=htons(6000);

bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);

sprintf(sendBuf,"Welcome%s to here!",inet_ntoa(addrClient.sin_addr));

send(sockConn,sendBuf,strlen(sendBuf)+1,0);

1:加载套接字库,创建套接字(WSAStartup()/socket());

2:向服务器发出连接请求(connect());

3:和服务器端进行通信(send()/recv());

4:关闭套接字,关闭加载的套接字库(closesocket()/WSACleanup())。

wVersionRequested= MAKEWORD( 1, 1);

err= WSAStartup( wVersionRequested,&wsaData);

if( LOBYTE( wsaData.wVersion)!= 1||

HIBYTE( wsaData.wVersion)!= 1){

SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);

addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");

addrSrv.sin_port=htons(6000);

connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

recv(sockClient,recvBuf,50,0);

send(sockClient,"hello",strlen("hello")+1,0);

2.基于UDP的socket编程是采用的数据报套接字。

在这个程序中,将两个工程添加到一个工作区。同时还要链接一个ws2_32.lib的库文件。

1:加载套接字库,创建套接字(WSAStartup()/socket());

2:绑定套接字到一个IP地址和一个端口上(bind());

3:等待和接收数据(sendto()/recvfrom());

4:关闭套接字,关闭加载的套接字库(closesocket()/WSACleanup())。

wVersionRequested= MAKEWORD( 1, 1);

err= WSAStartup( wVersionRequested,&wsaData);

if( LOBYTE( wsaData.wVersion)!= 1||

HIBYTE( wsaData.wVersion)!= 1)

SOCKET sockSrv=socket(AF_INET,SOCK_DGRAM,0);

addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);

addrSrv.sin_port=htons(7003);

bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

recvfrom(sockSrv,recvBuf,50,0,(SOCKADDR*)&addrClient,&len);

对于基于UDP的socket客户端来说,要进行如下步骤:

wVersionRequested= MAKEWORD( 2, 2);

err= WSAStartup( wVersionRequested,&wsaData);

if( LOBYTE( wsaData.wVersion)!= 2||

HIBYTE( wsaData.wVersion)!= 2){

SOCKET sockClient=socket(AF_INET,SOCK_DGRAM,0);

addrClient.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");

addrClient.sin_family=AF_INET;

addrClient.sin_port=htons(8889);

sendto(sockClient,"hi",3,0,(SOCKADDR*)&addrClient,sizeof(SOCKADDR));

1.socket(int domain,int type,int protocol):建立套接字;

2.bind(int sockid,struct sockaddr*addrp,socklen_t addrlen):把本机地址和端口跟上一步建立的socket绑定在一起;

3.listen(int sockid,int qsize):监听某套接字;

4.fd=accept(int sockid,struct sockaddr*callerid,socklen_t*addrlenp):等待某套接字接收信息;

5.recv(int fd,void*buf,size_t nbytes,int flags):从套接字接收数据;

2.connect(int sockid,struct sockaddr*serv_addrp,socklen_t addrlen):连接到服务器;

3. send(int sockfd,const void*buf,size_t nbytes,int flags):发送数据到服务器.

3. recvfrom(int sockfd,void*buff,size_t nbytes,int flags,struct sockaddr*from,socklen_t*addrlen):在套接字口接收数据,并且记录下接收到的数据来源;一定要注意这里的参数addrlen,它不仅是函数的输出,也是函数的输入!所以要在调用该函数之前对addrlen赋值sizeof(struct sockaddr)。否则返回的地址from将会出错!

2. sendto(int sockfd,const void*buff,size_t nbytes,int flags,const struct sockaddr*to,socklen_t addrlen):往指定的地址发送数据;

wwW.Xtw.Com.cN系统网专业的PC、手机系统开发下载平台,HarmonyOS系统、安卓、OS、windows电脑重装系统在线下载安装,操作系统平台技术学习,攻略教程,技术交流。

免责声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。内容仅供参考使用,不准确地方联系删除处理!

联系邮箱:773537036@qq.com