数据的网络传输是一个比较复杂的问题,其中有很多复杂性,硬件和软件的差异增加了问题的复杂性。所以统一的规则或标准绝对是重要的。另一方面,如何简化复杂的问题也需要考虑,就像编程的分治法(面向对象的对象或类,面向过程的函数都是分治思想的体现) ),所以在很多实践中都有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的参数不同
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();
}
-结束-
请登录后发表评论
注册
社交帐号登录