linux UDP编程学习总结

与TCP的不同

使用TCP套接口必须先要建立连接,而UDP套接口不需要预先建立连接,它在调用socket()生成一个套接口后,在服务器端调用bind()绑定端口,服务器阻塞于recvfrom()调用,客户端调用sendto()发送数据请求,阻塞于recvfrom()调用,服务器端调用recvfrom()接受数据,服务器端额调用sendto()向客户发送数据作为应答,然后阻塞于recvfrom()调用,客户端调用recvfrom()接收数据。

主要系统调用

函数(1):int recvfrom(int sockfd,void *buf,int len,inf flags,struct sockaddr *fromaddr,

socketlen_t *addrlen);

头文件:sys/socket.h

说明:函数返回实际读取的字节数,可以为0,错误返回-1。

函数(2):int sendto(int sockfd,void *buf,int len,int flag,struct sockaddr *toaddr,

socklen_t addrlen);

头文件:sys/socket.h

说明:函数返回实际写入段字节数,可以为0,出差返回-1。

UDP编程注意

由于UDP是无连接,不可靠的协议,没有TCP那样有重传确认的机制,因此在UDP编程中要注意数据可靠性的问题,主要包括:数据包的丢失,服务器进程未启动,数据源的可靠性等。

数据包的丢失可以采用设置一个定时器使用超时重传并使用序列号的可靠性机制等;数据源的可靠性,可以在客户端对数据源进行校验的机制等。

测试示例

服务端测试代码

#include <sys/types.h>

#include <sys/socket.h>

#include <unistd.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <stdio.h>

#include <stdlib.h>

#include <errno.h>

#include <netdb.h>

#include <stdarg.h>

#include <string.h>

 

#define MYPORT 4950

#define MAXSIZE 80

 

void str_ser(int sockfd);

int main(void)

{

       int sockfd;

       struct sockaddr_in my_addr;

       struct sockaddr_in their_addr;

       int addr_len;

       if((sockfd=socket(AF_INET,SOCK_DGRAM,0))==-1){

              printf("error in socket\n");

              exit(1);

       }    

       my_addr.sin_family=AF_INET;

       my_addr.sin_port=htons(MYPORT);

       my_addr.sin_addr.s_addr=htonl(INADDR_ANY);

       memset(my_addr.sin_zero,0,8);

       if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))==-1){

              printf("error in binding\n");

              exit(1);

       }

       str_ser1(sockfd);

       close(sockfd);

       exit(1);

}

 

void str_ser(int sockfd)

{

       char recvs[MAXSIZE];

       int n=0,len;

       struct sockaddr addr;

       while(1){

              len=sizeof(struct sockaddr_in);

              printf("waiting for data...\n");

              if((n=recvfrom(sockfd,recvs,MAXSIZE,0,(struct sockaddr *)&addr,&len))==-1){

                     printf("error receiving\n");

                     exit(1);

              }

              *(recvs+n-1)=0x00;

              printf("Received [%s],return to client immediately\n",recvs);

              strcpy(recvs,"ok");

              sendto(sockfd,recvs,n,0,(struct sockaddr *)&addr,len);

       }

}

客户端测试代码:

#include <sys/types.h>

#include <sys/socket.h>

#include <unistd.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <stdio.h>

#include <stdlib.h>

#include <errno.h>

#include <netdb.h>

#include <stdarg.h>

#include <string.h>

 

#define MYPORT 4950

#define MAXSIZE 80

 

void str_cli(FILE *fp,int sockfd, struct sockaddr *addr,int addrlen);

int main(int argc,char * argv[])

{

       int sockfd,ret,len;

       struct sockaddr_in their_addr;

       char *myname;

       struct in_addr **addrs;

       struct hostent *sh;

       if(argc!=2){

              printf("parameters not match\n");

              exit(0);

       }

       if((sh=gethostbyname(argv[1]))==NULL){

              printf("ERROR  when gethostby name\n");

              exit(0);

       }

       sockfd=socket(AF_INET,SOCK_DGRAM,0);

       if(sockfd<0){

              printf("error in socket\n");

              exit(1);

       }

       their_addr.sin_family=AF_INET;

       their_addr.sin_port=htons(MYPORT);

       their_addr.sin_addr=*((struct in_addr *)sh->h_addr);

       memset(their_addr.sin_zero,0,8);

       connect(sockfd,(struct sockaddr*)&their_addr,sizeof(struct sockaddr));

       str_cli(stdin,sockfd,(struct sockaddr *)&their_addr,sizeof(struct sockaddr_in));

       close(sockfd);

       exit(0);

}

 

 

void str_cli(FILE *fp,int sockfd,struct sockaddr * addr,int addrlen)

{

       char sends[MAXSIZE],recvs[MAXSIZE];

       int len,n=0;

       struct sockaddr *reply;

       while(fgets(sends,MAXSIZE,fp)!=NULL){

              sendto(sockfd,sends,strlen(sends),0,addr,addrlen);

              len=addrlen;

              n=recvfrom(sockfd,recvs,MAXSIZE,0,reply,&len);

              if(n==-1){

                     printf("error receiving data\n");   

                     exit(1);

              }

              if((len==addrlen)&& (memcmp(addr,reply,len)!=0)){

                     printf("message igored\n");

                     continue;

              }

              recvs[n]=0x00;

              fputs(recvs,stdout);

       }    


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值