歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> 關於Linux >> 嵌入式linux的網絡編程(4)--UDPServer程序設計

嵌入式linux的網絡編程(4)--UDPServer程序設計

日期:2017/3/1 13:46:44   编辑:關於Linux

嵌入式linux的網絡編程(4)--UDP Server程序設計

前面介紹了基於TCP的通信程序的設計,TCP協議實現了連接的,可靠的,傳輸數據流的傳輸控制協議,而UDP是非連接的,不可靠的,傳遞數據報的傳輸協議.由於UDP不提供可靠性保證,使得具有較少的傳輸時延,因而UDP協議常常用在一些對速度要求較高的場合.

1.UDP的通信過程

UDP通信的基本過程如下:在服務器端,服務器首先創建一個UDP數據報類型的套接字,該socket的類型為SOCK_DGRAM;然後服務器端調用bind函數,給比UDP套接字綁定一個端口.由於不需要建立連接,因此服務器端就可以通過調用recvfrom函數在指定的端口等待客戶端發送來的UDP數據報.在客戶端,同樣要先通過socket函數創建一個數據報套接字,然後由操作系統為這個套接字分配端口號.此後客戶端就可以使用sendto函數向一個地址發送一個UDP數據報.服務器端接收到數據後,從recvfrom中返回,在對數據進行處理後,再調用sendto函數將處理的結果返回客戶端.UDP連接的通信過程如下圖所示:

可見,UDP連接的通信過程相對於TCP連接的來說要簡單不少.由於UDP服務器進程不需要向TCP協議的服務器那樣要在傾聽套接字上接收新建的連接,而只需要在綁定的端口上等待客戶端發來的數據報,因此UDP服務器通常以循環的方式進行工作.

還有一點不同之處,TCP服務器通常在於客戶端建立連接後就被一個客戶端獨占,若要實現能同時為多個客戶端提供服務,則需要采取多個服務器子線程或子進程.而UDP服務器並不同客戶機建立連接,所以客戶機並不會獨占UDP服務器.例如,DNS服務器采用的UDP協議,當服務器處理完某個客戶端發來的數據報後,便可理解去處理另外一個客戶端的數據報,中間省略了許多費時的建立連接和銷毀連接的過程.提高了服務器的處理容量.

2.UDP通信服務器端

下面我們來看一個UDP服務器端程序的例子.下一篇文章會講解客戶端程序的編寫.

/**************************************************************************************/
/*簡介:UDPServer示例。										 */
/*************************************************************************************/
#include <stdio.h>        
#include <stdlib.h>
#include <strings.h>      
#include <unistd.h>       
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h>

#define PORT 2000           /* 監聽端口 */ 
#define MAXDATASIZE 100     /* 緩沖區的大小 */ 
#define STR "Welcome to my server.\n"

int main() 
{
	int sockfd;
	/* 服務器的地址信息 */ 
	struct sockaddr_in server; 
	/* 客戶端的地址信息 */ 
	struct sockaddr_in client; 
	int sin_size; 
	int num;
	/* 接收緩沖區 */
	char msg[MAXDATASIZE];  

	/* 創建UDP套接字  */
	if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)  
	{
		perror("Creating socket failed.");
		exit(1);
	}

	bzero(&server,sizeof(server));
	server.sin_family=AF_INET; 
	server.sin_port=htons(PORT); 
	server.sin_addr.s_addr = htonl (INADDR_ANY); 
	if (bind(sockfd, (struct sockaddr *)&server, \
				sizeof(struct sockaddr)) == -1) 
	{ 
		/* handle exception */
		perror("Bind error.");
		exit(1); 
	}    

	sin_size=sizeof(struct sockaddr_in); 
	while (1)   
	{
		num = recvfrom(sockfd,msg,MAXDATASIZE,0,\
				(struct sockaddr *)&client,&sin_size);                                    
		if (num < 0)
		{
			perror("recvfrom error\n"); 
			exit(1); 
		} 

		msg[num] = '\0';
		printf("You got a message (%s) from %s\n",msg,\
				inet_ntoa(client.sin_addr) );  
		/*向客戶端發送消息*/
		sendto(sockfd,STR,strlen(STR),0,\
				(struct sockaddr *)&client,sin_size);
		/*若消息是quit,則退出服務器程序*/
		if (!strcmp(msg,"quit")) break;
	} 
	/*關閉套接字*/    
	close(sockfd);  
	return 0;
}

這個服務器要實現的功能是:創建一個UDP的socket,在端口2000上等待數據報.當收到信的數據報後,獲得客戶端發來的消息,而後根據數據報中包含的發送者的地址信息,向客戶端發回一條歡迎信息,最後判斷該消息是否為退出命令,如果不是就繼續上述的工作,否則就結束服務器進程.

Copyright © Linux教程網 All Rights Reserved