赞
踩
其中16为UDP长度表示为整个数据报(UDP报头信息+UDP数据)的最大长度,那么也就是说UDP发送的数据最大不能超过64K(包括UDP报头信息)由于64K在当今的互联网下是非常非常小的数字,所以当我们要传输的数据超过64K时,就需要在应用层手动的分包,多次发送,并且在接收端手动的拼装。其中UDP检验和是为了校验数据的对错的,如果错误,直接丢弃,并不会重传。
UDP传输的过程是不需要连接的,也就是说客户端可以直接给服务器发送数据,并不需要创建链接,只需要知道目的主机IP地址与端口号即可发送。并且在发送数据的过程中,没有确认机制以及重传机制(确认机制就是目的主机收到源主机的信息时对其回复收到信息,这就是确认机制。重传机制就是在传输过程中,由于某些原因,导致丢失数据包,目的主机会对源主机进行反馈,然后重传丢失数据包)。如果因为某些故障原因导致数据没有发送到目的主机,UDP协议层并不会给应用层返回任何错误信息。UDP传输时,应用层交给它多长的报文数据,UDP原样发送,不会拆分与合并。
总结起来UDP的特点为:
在使用UDP来传输时,如何接收的报文数据呢?我们知道,如果网络中有数据传输给该主机是由网卡驱动驱动网卡来获取数据,而当网卡缓冲区内部有数据时,操作系统如何获取呢?
这里是由中断的方式来让操作系统处理显卡缓冲区内部的数据。其中中断分为两个部分,中断为上部分比较简单,并且紧急,下半部分为处理。这里的紧急意思为优先级就较高,一般情况下,操作系统判断出显卡缓冲区内有数据时,便会将其数据加载至操作系统内核缓冲区。加载完毕后,不一定立即对其继续数据处理分析。当
积累的报文信息很多时,便对这些报文信息进行描述与组织,对其进行管理。
UDP具有接收缓冲区的,这个接收缓冲区不能保证收到的UDP报的顺序与发送UDP报的顺序一致。如果缓冲区满了,后面到达的数据就会被丢弃。
UDP的socket既能读,也能写,这个概念叫做全双工。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(int argc, char* argv[])
{
if(argc != 3) { //判断命令行的合法性
printf("usage %s [IP] [port]\n", argv[0]);
return 1;
}
int sock = socket(AF_INET, SOCK_DGRAM, 0);//创建套接字
if(sock < 0) {
printf("socket error!\n");
return 2;
}
//声明sockaddr_in结构体,并填充
struct sockaddr_in local;
local.sin_family = AF_INET;
local.sin_port = htons(atoi(argv[2]));//转化端口号为网络字节格式
//inet_addr返回的地址已经是网络字节格式
//无需调用htonl转化为网络字节格式
local.sin_addr.s_addr = inet_addr(argv[1]);
//绑定套接字
if(bind(sock, (struct sockaddr*)&local, sizeof(local)) < 0) {
printf("bind error!\n");
return 3;
}
char buf[1024];
struct sockaddr_in client;
while(1) {
socklen_t len = sizeof(client);
buf[0] = 0;
ssize_t s = recvfrom(sock, buf, sizeof(buf) - 1, 0,
(struct sockaddr*)&client, &len);
if(s > 0) {
buf[s] = 0;
printf("[%s|%d]:%s\n",inet_ntoa(client.sin_addr), ntohs(client.sin_port), buf);
sendto(sock, buf, strlen(buf), 0,
(struct sockaddr*)&client, len);
}
}
close(sock);
return 0;
}
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(int argc, char* argv[])
{
if(argc != 3) {
printf("usage %s [IP] [port]\n", argv[0]);
return 1;
}
int sock = socket(AF_INET, SOCK_DGRAM, 0);
if(sock < 0) {
printf("socket error!\n");
return 2;
}
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(atoi(argv[2]));
server.sin_addr.s_addr = inet_addr(argv[1]);
char buf[1024];
struct sockaddr_in peer;
while(1) {
socklen_t len = sizeof(peer);
buf[0] = 0;
printf("please enter#");
fflush(stdout);
ssize_t s = read(0, buf, sizeof(buf) - 1);
if(s < 0) {
printf("read error!\n");
return 3;
}
buf[s-1] = 0;
sendto(sock, buf, strlen(buf), 0,
(struct sockaddr*)&server, sizeof(server));
s = recvfrom(sock, buf, sizeof(buf) - 1, 0,
(struct sockaddr*)&peer, &len);
if(s < 0) {
printf("recvfrom error!\n");
return 4;
}
buf[s] = 0;
printf("peer return %s\n", buf);
}
close(sock);
return 0;
}
欢迎大家共同讨论,如有错误及时联系作者指出,并改正。谢谢大家!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。