UDP类型的C/S简单实例

与TCP类型的C/S相比较,UDP缺少了connetc(),listen(),acept()函数,这是用于UDP协议无连接的特性,不用维护TCP的连接,断开状态

服务器端大体的流程为建立套接字,套接字与地址结构进行绑定,收发数据,关闭套接字,分别对应于函数socket(),bind(),sendto()

recvfrom()和close

先建立套接字文件描述符,使用函数socket(),生成套接字描述符

#include
#include
int socket(int domain,int type,int protocol);

用户调用socket函数,然后这个函数调用系统调用函数sys_socket(),系统调用sys_socket()分为两部分,一部分生成内核socket结构,另一部分与文件描述符进行绑定,将绑定的文件描述符返回。

所以我们可以通过访问套接字描述符的方式去和内核空间交互

然后第二步就是将套接字描述符与一个地址结构绑定在一起,使用函数bind

#include
#include
int bind(int sockfd,const struct sockaddr *my_addr,socklen_t addrlen);

与TCP并没有什么差异,bind()函数的作用是将一个套接字文件描述符与一个本地地址绑定在一起,即把发送数据的端口地址和IP地址进行了指定。

当成绑定之后,就可以使用recvfrom接收数据了

#include
#include
ssize_t recv(int s,void *buf,size_t len,int flags);
ssize_t recvfrom(int s,void *buf,size_t len,int flags,struct sockaddr  *from,socklen_t *fromlen);

可以看出来recvfrom主要是比recv函数多了一个本地地址结构,所以不需要进行连接,只需要接收时指定发送方地址就可以

然后下来是我们的客户端

大体为创建套接字,提取服务器端地址结构,收发数据

前面两个步骤上面有提到,主要是发数据的话,要用到sendto()

#include
#include
ssize_t send(int s,const void*buf,size_t len,int flags);
ssize_t sendto(int s,const void *buf,size_t len,int flags,const struct sockaddr *to,socklen_t tolen);

和send主要区别就在于第4个参数,表示接收数据的主机地址信息,第5个参数为第4个参数所指向内容的长度

具体代码如下

服务器端

#include                                                                                                                                                                             
#include
#include
#include
#include
#include
#include
#define BUFF_LEN 256
void udpserv_echo(int s,struct sockaddr *client)
{
    int n;                              //接收数据长度
    char buff[BUFF_LEN];                //接收发送缓冲区
    socklen_t   len;                    //地址长度
    while(1) {
        len = sizeof(*client);
        n = recvfrom(s,buff,BUFF_LEN,0,client,&len);
        sendto(s,buff,n,0,client,len);  //将接收到的字符发送回客户端
    }
}
int main(void)
{
    int s;                              //套接字文件描述符
    struct sockaddr_in  local;          //本地的地址信息
    struct sockaddr_in  from;           //发送方的地址信息
    int from_len = sizeof(from);        //地址结构的长度
    int n;                              //接收到的数据长度
    char buf[128];                      //接受数据缓冲区
    s= socket(AF_INET,SOCK_DGRAM,0);    //初始化一个IPV4族的数据报套接字
    if(-1 == s) {
        perror("");
        exit(EXIT_FAILURE);
    }
 
    local.sin_family = AF_INET;
    local.sin_port = htons(8888);
    local.sin_addr.s_addr = htonl(INADDR_ANY);
 
    bind(s,(struct sockaddr *)&local,sizeof(local));
    udpserv_echo(s,(struct sockaddr *)&from);   //回显处理函数
    return 0;
}

客户端

#include                                                                 
#include                                                                     
#include                                                                    
#include                                                                
#include                                                                
#include                                                                    
#define PORT_SERV 8888                                                                
#define BUFF_LEN 256                                                                  
void udpclie_echo(int s,struct sockaddr *to)                                          
{                                                                                     
    char buff[BUFF_LEN];                                                              
    struct sockaddr_in from;                                                          
    socklen_t len = sizeof(*to);                                                      
    sendto(s,buff,BUFF_LEN,0,to,len);                               //发送给服务器    
    recvfrom(s,buff,BUFF_LEN,0,(struct sockaddr *)&from,&len);      //从服务器接收数据                                                                                                        
    printf("recved:%s\n",buff);                                                       
}                                                                                     
int main(int argc,char *argv[])                                                       
{                                                                                     
    int s;                                                          //文件描述符      
    struct sockaddr_in addr_serv;                                   //地址结构        
    s = socket(AF_INET,SOCK_DGRAM,0);                               //建立UDP类型套接字
    memset(&addr_serv,0,sizeof(addr_serv));                         //清空地址结构    
    addr_serv.sin_family = AF_INET;                                                   
    addr_serv.sin_addr.s_addr = htonl(INADDR_ANY);                                    
    addr_serv.sin_port = htons(PORT_SERV);                          //服务器端口      
                                                                                      
    udpclie_echo(s,(struct sockaddr *)&addr_serv);                  //与服务器交互    
    close(s);                                                                         
    return 0;                                                                         
} 

 

你可能感兴趣的:(UDP类型的C/S简单实例)