linux网络编程(三)——UDP编程

来源:互联网 发布:java和net哪个比较好 编辑:程序博客网 时间:2024/06/04 08:28

前一篇文章介绍了linux网络编程中的TCP编程:http://blog.csdn.net/andoubi/article/details/51778988,本文主要介绍UDP编程。

UDP编程模型如下图所示:


与TCP传输数据相比,UDP传输数据前不需要建立连接。

1、具体用到的函数如下:
服务器端:
创建socket: socket()   绑定地址:bind()  发/收数据:sendto()/recvfrom()  结束连接:close()
客户机端:
创建socket: socket()   发/收数据:sendto()/recvfrom()  结束连接:close()

2、涉及函数详解:

与TCP编程相比,UDP编程知识数据的发送接收函数有变化,其它函数都是一样的。这里就介绍一些数据的发送接收函数。

2.1数据发送函数:sendto函数


destaddr是接收端套接字的地址。使用sendto函数发送数据,必须指定接收端套接字地址。在TCP编程中,send函数不需要指定地址,因为目标地址暗含在连接中了。

2.2数据接收函数:recvfrom函数


addr用来存储数据发送端套接字的地址。recvfrom函数在接收数据的同时也获取了发送端套接字地址。而在TCP编程中,是通过accept函数来获取与服务器建立连接的套接字地址。

3、实例(这些代码都是跟着国嵌的视频课程编写的,都是比较简单的功能)
编写一个UDP服务器程序和客户端程序,实现功能是:在客户端通过键盘输入一些字符,这些字符会发送到服务器,并在服务器上打印出来。

服务器端程序:

#include<stdio.h>#include<sys/socket.h>#include<string.h>#include<netinet/in.h>#include<arpa/inet.h>#include<stdlib.h>#define portnum 123//定义一个端口号#define MSG_SIZE 128int main(){int sockfd;struct sockaddr_in server_addr;struct sockaddr_in client_addr;char buffer[MSG_SIZE];int addr_len , n ;//地址长度//1 创建套接字if((sockfd=socket( AF_INET, SOCK_DGRAM, 0)) == -1)//如果创建套接字失败{printf("create socket error!\n");exit(1);}//2.1 初始化地址bzero(&server_addr, sizeof(struct sockaddr_in));server_addr.sin_family = AF_INET;server_addr.sin_port = htons( portnum);//转换成网络字节序server_addr.sin_addr.s_addr = htonl(INADDR_ANY );//INADDR_ANY:接收任何消息,转换成网络字节序//2.2 绑定地址bind( sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr) );//3 接收数据while(1){addr_len = sizeof(struct sockaddr);bzero(buffer, sizeof(buffer));//每次接收前,现将buffer清空n = recvfrom(sockfd, buffer, MSG_SIZE, 0,(struct sockaddr *)&client_addr,&addr_len);//打印出客户机地址printf("Receive data from:%s\n", (inet_ntoa(client_addr.sin_addr)) );buffer[n] = '\0';printf("server receive: %s\n", buffer);}//4 结束连接close(sockfd );return 0 ;}
客户端程序:(运行程序时,需要指定服务器地址)

#include<stdio.h>#include<sys/socket.h>#include<string.h>#include<netinet/in.h>#include<arpa/inet.h>#include<stdlib.h>#define BUF_SIZE 128#define PORT 123//端口必须与服务器一样int main( int argc, char **argv){int sockfd;char buffer[BUF_SIZE];struct sockaddr_in server_addr;if(argc!=2)//如果输入的包含命令名称在内的数据 !=2{printf("Usage: %s  server_ip\n", argv[0]);exit(1);}//1 创建套接字if((sockfd=socket( AF_INET, SOCK_DGRAM, 0)) == -1)//如果创建套接字失败{printf("create socket error!\n");exit(1);}//服务器地址初始化bzero(&server_addr, sizeof(struct sockaddr_in));server_addr.sin_family = AF_INET;server_addr.sin_port = htons( PORT);//转换成网络字节序inet_aton(argv[1],&server_addr.sin_addr);//将键盘输入的字符串格式地址,转化成整型IP //2 发送数据while(1){printf("Please input char:\n");fgets( buffer, BUF_SIZE,stdin);sendto(sockfd,buffer,strlen(buffer),0,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr));bzero(buffer,BUF_SIZE );//每次发送完,将buffer清空}//3关闭连接close( sockfd);}

对比:

TCP协议(传输控制协议)和UDP协议(用户数据报协议)的区别之一是:前者是面向链接的协议,后者是无连接协议。若要使用TCP来传输数据,则传输数据之前,客户端与服务器必须先建立连接。而使用UDP传输数据则不需要建立连接,只需要事先确定数据接收端套接字的地址。相比而言,使用TCP来传输数据要可靠的多。这里有一个简单的比喻来说明TCP和UDP传输数据的差异:

用UDP传输数据相当于给某人邮寄信件。虽然可以邮寄很多信件,但是无法保证信件的投递次序,且在邮递过程中有可能会丢失一些信件。每封信都写有收件人的地址,且没封信可能到达不同的接收者。

用TCP传输数据相当于给某人打电话。首先要通过电话建立一个连接,然后才能彼此双向通信。只有先接通电话才能聊天嘛。建立的每个连接都是端到端的通信通道。会话中不包含地址信息,就像呼叫的两端存在一个点对点的虚拟连接,并且连接本身暗含特定的源和目的地。


参考资料:《UNIX环境高级编程》

前一篇文章:linux网络编程(一)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

转载请注明出处:
作者:Andoubi
原文链接:http://blog.csdn.net/andoubi/article/details/52122748

    0 0