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);
} |