(都是些没营养的东西,tcp就懒得加了。socket在网上的东西实在太多了,写这个只因为想把开发板带的代码翻译一遍而已)
无聊的UDP
UDP协议的全称是用户数据报协议,在网络中它与TCP协议一样用于处理 数据包,是一种无连接的协议。在OSI模型中,在第四层——传输层,处于IP协议的上一层。
UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。UDP用来支持那些需要在计算机之间传输数据的网络应用。包括网络视频会议系统在内的众多的客户/服务器模式的网络应用都需要使用UDP协议。UDP协议从问世至今已经被使用了很多年,虽然其最初的光彩已经被一些类似协议所掩盖,但是即使是在今天UDP仍然不失为一项非常实用和可行的网络传输层协议。
由于UDP协议比较简单,作为linux的初学者可以很快的掌握程序的写法与思路。作为第一个所读较大的linux程序,希望大家重点理解库函数的调用与UDP的实现过程。调用驱动为并不是字符驱动(dm9000连x86的微机上都有),所以暂时不去了解。(udp网络广泛应用于我们的生活中,连qq的会话都是通过它实现的)
重点掌握函数:
Socket;
Sizeof;
memset;
htons;
atoi;
inet_pton;
bind;
fgets;
sendto;
recvfrom;
本程序相对于前面几个程序显得略微有些大,简单了解一下就好。
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdio.h>
#define BUFLEN 255 //输入字符最大值+1
int main(int argc, char **argv)
{
struct sockaddr_in peeraddr, localaddr;//一个简单的网络常用的结构体,指明地址信息
int sockfd; //寄存用于网络通信的嵌套字
char recmsg[BUFLEN+1];
int socklen, n; //储存sockaddr_in所占字节数
if(argc!=5){ //判断程序启动时穿的参数是否正确
printf("%s <dest IP address> <dest port> <source IP address> <source port>\n", argv[0]);
exit(0);
}
sockfd = socket(AF_INET, SOCK_DGRAM, 0);//创建一个能够进行网络通信的套接字
//TCP/IP协议,数据报套接字类型,0(1为关
//闭缓冲,实时传输???)
if(sockfd<0){
printf("socket creating err in udptalk\n");//创建失败报错
exit(1);
}
socklen = sizeof(struct sockaddr_in); //判断sockaddr_in所占字节数
memset(&peeraddr, 0, socklen); //清空结构体,将peeraddr中前socklen个字 //节替换为0并返回peeraddr的指针
peeraddr.sin_family=AF_INET;//设置结构体中sin_family为TCP/IP协议
peeraddr.sin_port=htons(atoi(argv[2])); //同理,IP设置为输入 //的对方IP端口 atoi()字符转整形htons的功能:将一个无
//符号短整型数值转换为网络字节序
if(inet_pton(AF_INET, argv[1], &peeraddr.sin_addr)<=0){
//将对方的ip存入peeraddr.sin_addr
printf("Wrong dest IP address!\n");
exit(0);
}
memset(&localaddr, 0, socklen);
//清空结构体,将localaddr中前socklen个字
//节替换为0并返回localaddr的指针
localaddr.sin_family=AF_INET;
//设置结构体中sin_family为TCP/IP协议
if(inet_pton(AF_INET, argv[3], &localaddr.sin_addr)<=0){
//将自己的ip存入localaddr.sin_addr
printf("Wrong source IP address!\n");
exit(0);
}
localaddr.sin_port=htons(atoi(argv[4]));
//同理,IP设置为输入的对方IP端口
//atoi()字符转整形htons的功能:将一个无符号短整型数值转换为网络 //字节序
if(bind(sockfd, &localaddr, socklen)<0){
//将嵌套字sockfd,与localaddr(本机)中地址捆绑
printf("bind local address err in udptalk!\n");
exit(2);
}
if(fgets(recmsg, BUFLEN, stdin) == NULL) exit(0);
//将标准输入stdin中的数据一行输入recmsg中最大BUFLEN-1个字符
if(sendto(sockfd, recmsg, strlen(recmsg), 0, &peeraddr, socklen)<0){
//将标准输入后的参数发送到peeraddr的地址上,recmsg内容,sockfd绑 //定地址的嵌套字…………
printf("sendto err in udptalk!\n");
exit(3);
}
for(;;){
/*recv&send message loop*/ //收到和发送消息循环
n = recvfrom(sockfd, recmsg, BUFLEN, 0, &peeraddr, &socklen);
<span style="white-space:pre"> </span>//接收这段百度百科吧,代码写的逻辑有些乱,不好加备注,看自己理解吧,反正数据自己都能看到
if(n<0){
printf("recvfrom err in udptalk!\n");
exit(4);
}else{
recmsg[n]=0;
printf("peer:%s", recmsg); //输出
}
if(fgets(recmsg, BUFLEN, stdin) == NULL) exit(0);//再输入
if(sendto(sockfd, recmsg, strlen(recmsg), 0, &peeraddr, socklen)<0){//在发送
printf("sendto err in udptalk!\n");
exit(3);
}
}
}