UDPClient代碼分享
前文,我們對(duì)UDP Server的編寫(xiě)過(guò)程進(jìn)行了分析和介紹,并且也分享了源碼,不知道大家掌握的如何。這里我們繼續(xù)來(lái)對(duì)UDPClient程序進(jìn)行一下分析,希望對(duì)大家有所幫助。
UDPClient程序
編寫(xiě)UDPClient程序的步驟
(1)初始化sockaddr_in結(jié)構(gòu)的變量,并賦值。這里使用“8888”作為連接的服務(wù)程序的端口,從命令行參數(shù)讀取IP地址,并且判斷IP地址是否符合要求。
(2)使用socket()來(lái)建立一個(gè)UDP socket,第二個(gè)參數(shù)為SOCK_DGRAM。
(3)使用connect()來(lái)建立與服務(wù)程序的連接。與TCP協(xié)議不同,UDP的connect()并沒(méi)有與服務(wù)程序三次握手。上面說(shuō)了UDP是非連接的,實(shí)際上也可以是連接的。使用連接的UDP,kernel可以直接返回錯(cuò)誤信息給用戶程序,從而避免由于沒(méi)有接收到數(shù)據(jù)而導(dǎo)致調(diào)用recvfrom()一直等待下去,看上去好像客戶程序沒(méi)有反應(yīng)一樣。
(4)向服務(wù)程序發(fā)送數(shù)據(jù),因?yàn)槭褂眠B接的UDP,所以使用write()來(lái)替代sendto()。這里的數(shù)據(jù)直接從標(biāo)準(zhǔn)輸入讀取用戶輸入。
(5)接收服務(wù)程序發(fā)回的數(shù)據(jù),同樣使用read()來(lái)替代recvfrom()。
(6)處理接收到的數(shù)據(jù),這里是直接輸出到標(biāo)準(zhǔn)輸出上。
udpclient.c程序內(nèi)容:
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #define MAXLINE 80
- #define SERV_PORT 8888
- void do_cli(FILE *fp, int sockfd, struct sockaddr *pservaddr, socklen_t servlen)
- {
- int n;
- char sendline[MAXLINE], recvline[MAXLINE + 1];
- /* connect to server */
- if(connect(sockfd, (struct sockaddr *)pservaddr, servlen) == -1)
- {
- perror("connect error");
- exit(1);
- }
- while(fgets(sendline, MAXLINE, fp) != NULL)
- {
- /* read a line and send to server */
- write(sockfd, sendline, strlen(sendline));
- /* receive data from server */
- n = read(sockfd, recvline, MAXLINE);
- if(n == -1)
- {
- perror("read error");
- exit(1);
- }
- recvline[n] = 0; /* terminate string */
- fputs(recvline, stdout);
- }
- }
- int main(int argc, char **argv)
- {
- int sockfd;
- struct sockaddr_in srvaddr;
- /* check args */
- if(argc != 2)
- {
- printf("usage: udpclient \n");
- exit(1);
- }
- /* init servaddr */
- bzero(&servaddr, sizeof(servaddr));
- servaddr.sin_family = AF_INET;
- servaddr.sin_port = htons(SERV_PORT);
- if(inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
- {
- printf("[%s] is not a valid IPaddress\n", argv[1]);
- exit(1);
- }
- sockfd = socket(AF_INET, SOCK_DGRAM, 0);
- do_cli(stdin, sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
- return 0;
- }