前文,我们对UDP Server的编写过程进行了分析和介绍,并且也分享了源码,不知道大家掌握的如何。这里我们继续来对UDPClient程序进行一下分析,希望对大家有所帮助。
UDPClient程序
编写UDPClient程序的步骤
(1)初始化sockaddr_in结构的变量,并赋值。这里使用“8888”作为连接的服务程序的端口,从命令行参数读取IP地址,并且判断IP地址是否符合要求。
(2)使用socket()来建立一个UDP socket,第二个参数为SOCK_DGRAM。
(3)使用connect()来建立与服务程序的连接。与TCP协议不同,UDP的connect()并没有与服务程序三次握手。上面说了UDP是非连接的,实际上也可以是连接的。使用连接的UDP,kernel可以直接返回错误信息给用户程序,从而避免由于没有接收到数据而导致调用recvfrom()一直等待下去,看上去好像客户程序没有反应一样。
(4)向服务程序发送数据,因为使用连接的UDP,所以使用write()来替代sendto()。这里的数据直接从标准输入读取用户输入。
(5)接收服务程序发回的数据,同样使用read()来替代recvfrom()。
(6)处理接收到的数据,这里是直接输出到标准输出上。
udpclient.c程序内容:
- #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;
- }