發新話題

[分享] Linux網絡編程--5. 用戶數據報發送

Linux網絡編程--5. 用戶數據報發送

    我們前面已經學習網絡程序的一個很大的部分,由這個部分的知識,我們實際上可以寫出大部分的基於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協議的.

TOP

發新話題

本站所有圖文均屬網友發表,僅代表作者的觀點與本站無關,如有侵權請通知版主會盡快刪除。