TCP/IP 協定與 Internet 網路:第八章 TCP Socket 程式介面  上一頁           下一頁

 

翻轉工作室:粘添壽

 

8-7 電報傳輸程式範例

        如同虛擬電路之範例程式一樣功能,我們再開發電報傳輸模式而建構在 UDP 協定上。Client 端和 Server 端範例程式為:updsrv.c udpcln.c,編譯與執行方式也和虛擬電路範例一樣:

Server 程式編譯及執行:(Server 主機位於:163.15.2.30

# cc –o udpsrv udpsrv.c

# udpsrv &

Client 程式編譯及執行:(Client 主機位於:163.15.2.62

# cc –o udpcln udpcln.c

# udpcln 163.15.2.30 file_a

8-7-1 UDP 伺服端程式範例

UDP 伺服端程式為 udpsrv.c,程式範例如下:(請參考圖 8-5,執行步驟大略和 TCP 相同,不再另述)

/***  UDP Server(udpsrv.c)  

 *

 * 利用 socket 介面設計網路應用程式

 * 程式啟動後等待 client 端連線,連線後印出對方之 IP 位址

 * 並顯示對方所傳遞之訊息,並回送給 Client 端。

 *

 */

#include <stdio.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <sys/errno.h>

 

#define SERV_PORT 5134

 

#define MAXNAME 1024

 

extern int errno;

 

main()

{

       int socket_fd;   /* file description into transport */

       int recfd; /* file descriptor to accept        */

       int length;      /* length of address structure      */

       int nbytes;      /* the number of read **/

       char buf[BUFSIZ];

       struct sockaddr_in myaddr; /* address of this service */

       struct sockaddr_in client_addr; /* address of client    */

/*                             

 *      Get a socket into UDP/IP

 */

       if ((socket_fd = socket(AF_INET, SOCK_DGRAM, 0)) <0) {

             perror ("socket failed");

             exit(1);

       }

/*

 *    Set up our address

 */

       bzero ((char *)&myaddr, sizeof(myaddr));

       myaddr.sin_family = AF_INET;

       myaddr.sin_addr.s_addr = htonl(INADDR_ANY);

       myaddr.sin_port = htons(SERV_PORT);

 

/*

 *     Bind to the address to which the service will be offered

 */

       if (bind(socket_fd, (struct sockaddr *)&myaddr, sizeof(myaddr)) <0) {

             perror ("bind failed\n");

             exit(1);

       }

 

/*

 *   Loop continuously, waiting for datagrams

 *   and response a message

 */

       length = sizeof(client_addr);

       printf("Server is ready to receive !!\n");

       printf("Can strike Cntrl-c to stop Server >>\n");

 

       while (1) {

             if ((nbytes = recvfrom(socket_fd, &buf, MAXNAME, 0,

                       &client_addr, &length)) <0) {

                    perror ("could not read datagram!!");

                    continue;

               }

 

                          

             printf("Received data form %s : %d\n",

             inet_ntoa(client_addr.sin_addr), htons(client_addr.sin_port));

             printf("%s\n", &buf);

      

             /* return to client */

             if (sendto(socket_fd, &buf, nbytes, 0, &client_addr, length)

                    < 0) {

                    perror("Could not send datagram!!\n");

                    continue;

             }

             printf("Can Strike Crtl-c to stop Server >>\n");

       }

}

 

8-7-2 UDP 客戶端程式範例

UDP 客戶端程式為 tcpcln.c,程式執行步驟大略和 TCP 客戶端相同不再另述,程式範例如下:(請參考圖 8-5

/*  TCP  Client program (tcpcln.c)

 *

 *  本程式啟動後向 Server (tcpserver) 要求連線,

 *  並送出某檔案給 Server,再由 Server 收回該檔案

 *  並顯示出該檔案的內容

 *

 */

 

#include <stdio.h>

#include <netdb.h>

#include <signal.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <fcntl.h>

 

#define SERV_PORT 5134

#define MAXDATA   1024

 

#define MAXNAME 1024

main(argc, argv)

int argc;

char **argv;

{

       int fd;                          /* fd into transport provider */

       int i;                               /* loops through user name */

       int length;                    /* length of message */

       int size;                    /* the length of servaddr */

       int fdesc;                   /* file description */

       int ndata;                  /* the number of file data */

       char data[MAXDATA];       /* read data form file */

       char data1[MAXDATA];      /*server response a string */

       char buf[BUFSIZ];           /* holds message from server */

       struct hostent *hp;           /* holds IP address of server */

       struct sockaddr_in myaddr;    /* address that client uses */

       struct sockaddr_in servaddr;   /* the server's full addr */

 

       /*

        * Check for proper usage.

        */

       if (argc < 3) {

             fprintf (stderr,

                    "Usage: %s host_name(IP address) file_name\n", argv[0]);

             exit(2);

       }

       /*

        *  Get a socket into TCP/IP

        */

       if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {

             perror ("socket failed!");

             exit(1);

       }

       /*

        * Bind to an arbitrary return address.

        */

       bzero((char *)&myaddr, sizeof(myaddr));

       myaddr.sin_family = AF_INET;

       myaddr.sin_addr.s_addr = htonl(INADDR_ANY);

       myaddr.sin_port = htons(0);

 

       if (bind(fd, (struct sockaddr *)&myaddr,

                    sizeof(myaddr)) <0) {

             perror("bind failed!");

             exit(1);

       }

       /*

        * Fill in the server's UDP/IP address

        */

 

       bzero((char *)&servaddr, sizeof(servaddr));

       servaddr.sin_family = AF_INET;

       servaddr.sin_port = htons(SERV_PORT);

       hp = gethostbyname(argv[1]);

 

       if (hp == 0) {

             fprintf(stderr,

                    "could not obtain address of %s\n", argv[2]);

             return (-1);

       }

 

       bcopy(hp->h_addr_list[0], (caddr_t)&servaddr.sin_addr,

             hp->h_length);

 

       /**開起檔案讀取文字 **/

       fdesc = open(argv[2], O_RDONLY);

       if (fdesc == -1) {

             perror("open file error!");

             exit (1);

       }

       ndata = read (fdesc, data, MAXDATA);

       if (ndata < 0) {

             perror("read file error !");

             exit (1);

       }

       data[ndata + 1] = '\0';

 

       /* 發送資料給 Server */

       size = sizeof(servaddr);

       if (sendto(fd, data, ndata, 0,

             &servaddr, size) == -1) {

             perror("write to server error !");

             exit(1);

       }

       /** 由伺服器接收回應 **/

       if (recvfrom(fd, data1, MAXDATA, 0, &servaddr, &size) < 0) {

             perror ("read from server error !");

             exit (1);

       }

       /* 印出 server 回應 **/

       printf("%s\n", data1);

 

}

 

 

<GOTOP>