基于UDP(面向无连接)的套接字编程来说程序

数据的网络传输是一个比较复杂的问题,其中有很多复杂性,硬件和软件的差异增加了问题的复杂性。所以统一的规则或标准绝对是重要的。另一方面,如何简化复杂的问题也需要考虑,就像编程的分治法(面向对象的对象或类,面向过程的函数都是分治思想的体现) ),所以在很多实践中都有OSI分层标准,通过分层来简化问题。在众多的网络互联协议中,有TCP/IP协议(名字只是代表两层,代表了整个四层协议)。 ),TCP/IP协议将OSI的七层简化为四层,无论是七层还是四层,每一层解决自己独立的问题,相互独立,建立相邻层的输入和输出。

应用层:什么样的网络应用(不同的网络应用需要考虑下层,即传输层的不同选择)?如http、smtp、ftp等;

传输层:如何实现可靠传输?如何实现实时或简单传输?如TCP、UDP等;

网络层:如何确定两端的地址?如何选择最佳路径?如IP、ARP等;

链路层:实际的比特流如何流动?如以太网等;

因此,网络应用程序可以使用 TCP 或 UDP 实现,但可靠性、实时性和复杂性各不相同,具体取决于需求。

编程面临复杂的协议,其复杂程度可想而知。为简化起见,socket socket是从应用层和传输层抽象出来的应用编程接口和套接字,作为接口层。只要熟悉十几个函数接口就可以了。

基于UDP(无连接)的socket编程的服务器端也称为接收端。对于基于UDP(无连接)的socket编程,server端和client端的概念不是很强,我们也可以叫server端,即先启动的端,接收端应用编程接口和套接字,发送端数据称为发送方,也称为客户端。

我们先来看看receiver程序的写法:

1 创建一个套接字。 2 将套接字绑定到本地地址和端口(绑定)。 3 等待接收数据(recv from)。 4 关闭插座。

代码:

//UDP服务器

#包括

#包括

#pragma comment(lib,”ws2_32.lib”)

void main()

{

WORD wVersionRequested;

WSADATA wsaData;

wVersionRequested = MAKEWORD(1, 1);

int err = WSAStartup(wVersionRequested, &wsaData);

如果(错误!= 0){返回; }

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

WSACleanup();返回; }

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

SOCKADDR_IN addrSrv;

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

addrSrv.sin_family=AF_INET;

addrSrv.sin_port=htons(6000);

绑定(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

char sendBuf[100],recvBuf[100],temp[200];

SOCKADDR_IN addrClent;

int len=sizeof(SOCKADDR);

而(1) {

recvfrom(sockSrv,recvBuf,100,0,(SOCKADDR*)&addrClent,&len);

if(‘q’==recvBuf[0]) {

sendto(sockSrv,”q”,strlen(“q”)+1,0,(SOCKADDR*)&addrClent,len);

printf(“聊天结束!\n”);

休息;

}

sprintf(temp,”%s:%s”,inet_ntoa(addrClent.sin_addr),recvBuf);

printf(“%s\n”,temp);

printf(“请输入数据:\n”);

获取(sendBuf);

sendto(sockSrv,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&addrClent,len);

}

closesocket(sockSrv);

WSACleanup();

}

要在控制台中使用套接字,需要添加头文件#include和库函数ws2_32.lib

添加ws2_32.lib:项目→设置→链接,添加库(前面有空格),或者//#pragma comment(lib,”ws2_32.lib”)

与TCP套接字编程相比,主要区别如下:

1 建立socket的参数不同

图片[1]-基于UDP(面向无连接)的套接字编程来说程序-老王博客

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

// SOCK_STREAM表示TCP连接,SOCK_DGRAM表示UDP连接

2 发送和接收消息的接口

发送到(); //有6个参数,TCP的send()只有4个参数; recvfrom() //有6个参数,而TCP的recv()只有4个参数;

//接收方代码

#包括

#包括

#pragma comment(lib,”ws2_32.lib”)

void main()

{

WORD wVersionRequested;

WSADATA wsaData;

错误;

wVersionRequested = MAKEWORD(1, 1);

err = WSAStartup(wVersionRequested, &wsaData);

如果(错误!= 0)

{

返回;

}

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

HIBYTE( wsaData.wVersion ) != 1 ) {

WSACleanup( );

返回;

}

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

SOCKADDR_IN addrSrv;

addrSrv.sin_addr.S_un.S_addr=inet_addr(“127.0.0.1”);

addrSrv.sin_family=AF_INET;

addrSrv.sin_port=htons(6000);

char sendBuf[100];

char recvBuf[100];

字符温度[200];

int len=sizeof(SOCKADDR);

而(1)

{

printf(“请输入数据\n”);

获取(sendBuf);

sendto(sockClient,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&addrSrv,

len);

recvfrom(sockClient,recvBuf,100,0,(SOCKADDR*)&addrSrv,

&len);

if(‘q’==recvBuf[0])

{

sendto(sockClient,”q”,strlen(“q”)+1,0,(SOCKADDR*)&addrSrv,len);

printf(“聊天结束!\n”);

休息;

}

sprintf(temp,”%s:%s”,inet_ntoa(addrSrv.sin_addr),recvBuf);

printf(“%s\n”,temp);

}

closesocket(sockClient);

WSACleanup();

}

-结束-

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论