Linux系统编程(37)—— socket编程之UDP服务器与客户端

 

典型的UDP客户端/服务器通讯过程:

 

 

 

编写UDP Client程序的步骤

1、初始化sockaddr_in结构的变量,并赋值。这里使用“8888”作为连接的服务程序的端口,从命令行参数读取IP地址,并且判断IP地址是否符合要求。

2、使用socket()来建立一个UDPsocket,第二个参数为SOCK_DGRAM。

3、使用connect()来建立与服务程序的连接。与TCP协议不同,UDP的connect()并没有与服务程序三次握手。上面说了UDP是非连接的,实际上也可以是连接的。使用连接的UDP,kernel可以直接返回错误信息给用户程序,从而避免由于没有接收到数据而导致调用recvfrom()一直等待下去,看上去好像客户程序没有反应一样。

4、向服务程序发送数据,因为使用连接的UDP,所以使用write()来替代sendto()。这里的数据直接从标准输入读取用户输入。

5、接收服务程序发回的数据,同样使用read()来替代recvfrom()。

6、处理接收到的数据,这里是直接输出到标准输出上。

 

以下是简单的UDP服务器和客户端程序。

 

/* server.c */
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include "wrap.h"
 
#define MAXLINE 80
#define SERV_PORT 8000
 
int main(void)
{
         structsockaddr_in servaddr, cliaddr;
         socklen_tcliaddr_len;
         intsockfd;
         charbuf[MAXLINE];
         charstr[INET_ADDRSTRLEN];
         inti, n;
 
         sockfd= Socket(AF_INET, SOCK_DGRAM, 0);
 
         bzero(&servaddr,sizeof(servaddr));
         servaddr.sin_family= AF_INET;
         servaddr.sin_addr.s_addr= htonl(INADDR_ANY);
         servaddr.sin_port= htons(SERV_PORT);
   
         Bind(sockfd,(struct sockaddr *)&servaddr, sizeof(servaddr));
 
         printf("Acceptingconnections ...\n");
         while(1) {
                   cliaddr_len= sizeof(cliaddr);
                   n= recvfrom(sockfd, buf, MAXLINE, 0, (struct sockaddr *)&cliaddr,&cliaddr_len);
                   if(n == -1)
                            perr_exit("recvfromerror");
                   printf("receivedfrom %s at PORT %d\n",
                          inet_ntop(AF_INET,&cliaddr.sin_addr, str, sizeof(str)),
                          ntohs(cliaddr.sin_port));
   
                   for(i = 0; i < n; i++)
                            buf[i]= toupper(buf[i]);
                   n= sendto(sockfd, buf, n, 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr));
                   if(n == -1)
                            perr_exit("sendtoerror");
         }
}

 

/* client.c */
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include "wrap.h"
 
#define MAXLINE 80
#define SERV_PORT 8000
 
int main(int argc, char *argv[])
{
         structsockaddr_in servaddr;
         intsockfd, n;
         charbuf[MAXLINE];
         charstr[INET_ADDRSTRLEN];
         socklen_tservaddr_len;
   
         sockfd= Socket(AF_INET, SOCK_DGRAM, 0);
 
         bzero(&servaddr,sizeof(servaddr));
         servaddr.sin_family= AF_INET;
         inet_pton(AF_INET,"127.0.0.1", &servaddr.sin_addr);
         servaddr.sin_port= htons(SERV_PORT);
   
         while(fgets(buf, MAXLINE, stdin) != NULL) {
                   n= sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)&servaddr,sizeof(servaddr));
                   if(n == -1)
                            perr_exit("sendtoerror");
 
                   n= recvfrom(sockfd, buf, MAXLINE, 0, NULL, 0);
                   if(n == -1)
                            perr_exit("recvfromerror");
          
                   Write(STDOUT_FILENO,buf, n);
         }
 
         Close(sockfd);
         return0;
}

 

由于UDP不需要维护连接,程序逻辑简单了很多,但是UDP协议是不可靠的,实际上有很多保证通讯可靠性的机制需要在应用层实现。

 

编译运行server,在两个终端里各开一个client与server交互,看看server是否具有并发服务的能力。用Ctrl+C关闭server,然后再运行server,看此时client还能否和server联系上。和前面TCP程序的运行结果相比较,体会无连接的含义。

 

 

 

转载于:https://www.cnblogs.com/new0801/p/6176965.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值