[ 永遠的UNIX::UNIX技術資料的寶庫 ]   GB | BIG5

首頁 > 編程技術 > 網絡編程 > 正文
Linux網絡編程--5. 用戶數據報發送
http://linuxc.51.net 作者:hoyt (2001-05-08 11:21:31)

    我們前面已經學習網絡程序的一個很大的部分,由這個部分的知識,我們實際上可以寫出大部分的基TCP協議的網絡程序了.現在在Linux下的大部分程序都是用我們上面所學的知識來寫的.我們可以去找一些源程序來參考一下.這一章,我們簡單的學習一下基UDP協議的網絡程序. 

5.1 兩個常用的函數 

   int recvfrom(int sockfd,void *buf,int len,unsigned int flags,struct sockaddr * from int *fromlen)
   int sendto(int sockfd,const void *msg,int len,unsigned int flags,struct sockaddr *to int tolen)

sockfd,buf,len的意義和read,write一樣,分別表示套接字描述符,發送或接收的緩沖區及大小.recvfrom負責從sockfd接收數據,如果from不是NULL,那在from裡面存儲了信息來源的情況,如果對信息的來源不感興趣,可以將from和fromlen設置為NULL.sendto負責向to發送信息.此時在to裡面存儲了收信息方的詳細資料. 


5.2 一個實例 

/*           服務端程序  server.c           */

#include 
#include 
#include 
#include 
#include 
#define SERVER_PORT     8888
#define MAX_MSG_SIZE    1024

void udps_respon(int sockfd)
{
        struct sockaddr_in addr;
        int     addrlen,n;
        char    msg[MAX_MSG_SIZE];
        
        while(1)
        {       /* 從網絡上度,寫到網絡上面去   */
                n=recvfrom(sockfd,msg,MAX_MSG_SIZE,0,
                        (struct sockaddr*)&addr,&addrlen);
                msg[n]=0;
                /* 顯示服務端已經收到了信息  */
                fprintf(stdout,"I have received %s",msg);
                sendto(sockfd,msg,n,0,(struct sockaddr*)&addr,addrlen);
        }
}

int main(void)
{
        int sockfd;
        struct sockaddr_in      addr;
        
        sockfd=socket(AF_INET,SOCK_DGRAM,0);
        if(sockfd<0)
        {
                fprintf(stderr,"Socket Error:%s\n",strerror(errno));
                exit(1);
        }
        bzero(&addr,sizeof(struct sockaddr_in));
        addr.sin_family=AF_INET;
        addr.sin_addr.s_addr=htonl(INADDR_ANY);
        addr.sin_port=htons(SERVER_PORT);
        if(bind(sockfd,(struct sockaddr *)&ddr,sizeof(struct sockaddr_in))<0)
        {
                fprintf(stderr,"Bind Error:%s\n",strerror(errno));
                exit(1);
        }
        udps_respon(sockfd);
        close(sockfd);
}


/*          客戶端程序             */
#include 
#include 
#include 
#include 
#include 
#include 
#define MAX_BUF_SIZE    1024

void udpc_requ(int sockfd,const struct sockaddr_in *addr,int len)
{
        char buffer[MAX_BUF_SIZE];
        int n;
        while(1)        
        {        /*   從鍵盤讀入,寫到服務端   */
                fgets(buffer,MAX_BUF_SIZE,stdin);
                sendto(sockfd,buffer,strlen(buffer),0,addr,len);
                bzero(buffer,MAX_BUF_SIZE);
                /*   從網絡上讀,寫到屏幕上    */
                n=recvfrom(sockfd,buffer,MAX_BUF_SIZE,0,NULL,NULL);
                buffer[n]=0;
                fputs(buffer,stdout);
        }
}

int main(int argc,char **argv)
{
        int sockfd,port;
        struct sockaddr_in      addr;
        
        if(argc!=3)
        {
                fprintf(stderr,"Usage:%s server_ip server_port\n",argv[0]);
                exit(1);
        }
        
        if((port=atoi(argv[2]))<0)
        {
                fprintf(stderr,"Usage:%s server_ip server_port\n",argv[0]);
                exit(1);
        }
        
        sockfd=socket(AF_INET,SOCK_DGRAM,0);
        if(sockfd<0)
        {
                fprintf(stderr,"Socket  Error:%s\n",strerror(errno));
                exit(1);
        }       
        /*      填充服務端的資料      */
        bzero(&addr,sizeof(struct sockaddr_in));
        addr.sin_family=AF_INET;
        addr.sin_port=htons(port);
        if(inet_aton(argv[1],&addr.sin_addr)<0)
        {
                fprintf(stderr,"Ip error:%s\n",strerror(errno));
                exit(1);
        }
        udpc_requ(sockfd,&addr,sizeof(struct sockaddr_in));
        close(sockfd);
}

########### 編譯文件 Makefile        ##########
all:server client
server:server.c
        gcc -o server server.c
client:client.c
        gcc -o client client.c
clean:
        rm -f server
        rm -f client
        rm -f core

上面的實例如果大家編譯運行的話,會發現一個小問題的. 在我機器上面,我先運行服務端,然運行客戶端.在客戶端輸入信息,發送到服務端, 在服務端顯示已經收到信息,但是客戶端沒有反映.再運行一個客戶端,向服務端發出信息 卻可以得到反應.我想可能是第一個客戶端已經阻塞了.如果誰知道怎解決的話,請告訴我,謝謝. 由UDP協議是不保証可靠接收數據的要求,所以我們在發送信息的時候,系統並不能夠保証我們發出的信息都正確無誤的到達目的地.一般的來說我們在編寫網絡程序的時候都是選用TCP協議的. 
(http://www.fanqiang.com)
    進入【UNIX論壇

相關文章
Proxy源代碼分析--談談如何學習linux網絡編程 (2001-08-10 12:00:00)
Linux網絡編程--10. 原始套接字 --11. 記 (2001-05-08 11:26:09)
Linux網絡編程--9. 服務器模型 (2001-05-08 11:23:59)
Linux網絡編程--8. 套接字選項 (2001-05-08 11:23:24)
Linux網絡編程--7. TCP/IP協議 (2001-05-08 11:22:40)
Linux網絡編程--6. 高級套接字函數 (2001-05-08 11:22:09)
Linux網絡編程--5. 用戶數據報發送 (2001-05-08 11:21:31)
Linux網絡編程--4. 完整的讀寫函數 (2001-05-08 11:20:52)
Linux網絡編程--3. 服務器和客戶機的信息函數 (2001-05-08 11:20:14)
Linux網絡編程--2. 初等網絡函數介紹(TCP) (2001-05-08 11:19:34)

===更多相關===
 

★  樊強制作 歡迎分享  ★