码迷,mamicode.com
首页 > 其他好文 > 详细

Unix网络编程之UDP实例

时间:2016-05-12 14:55:18      阅读:156      评论:0      收藏:0      [点我收藏+]

标签:

首先先看一下UDP客户/服务器交互的典型情形,如下图:

技术分享

由上图可知,客户端程序不需要与服务器端建立连接,只需要调用sendto函数向服务器发送数据,或者调用recvfrom函数从服务器接收数据即可。最明显地特点就是服务器端只是比客户端多调用了一个bind函数来显式绑定一个端口。事实上客户端也可以通过bind来绑定端口,只不过没有那个必要。

实例代码:

//server.c

#include <stdlib.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>

int main()
{
    int sockfd;
    struct sockaddr_in servaddr,clientaddr;
    char recv[1024];
    socklen_t len;   

    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
   
    memset(&servaddr, ‘\0‘, sizeof(servaddr));
    memset(recv, ‘\0‘, 1024);
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons( 5000 );

    bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));

    for( ; ; )
    {
        recvfrom(sockfd, recv, 1024, 0, (struct sockaddr *)&clientaddr, &len);
        printf("%s\n", recv);
        memset(recv, ‘\0‘, 1024);
    }

    close(sockfd);
}


//client.c

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>

int main()
{
    int sockfd;
    struct sockaddr_in servaddr;
    memset(&servaddr, ‘\0‘, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons( 5000 );
    servaddr.sin_addr.s_addr = inet_addr("192.168.59.129");   
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    sendto(sockfd, "hello", 5, 0, (struct sockaddr *)&servaddr, sizeof(servaddr));
    close(sockfd);
    return 0;
}


基于UDP的服务器的特点:

1.在服务器端,应该提供的是一个迭代服务器,而不是像TCP服务器那样可以提供一个并发服务器。一般来说,大多数TCP服务器是并发的,而大多数UDP服务器是迭代的。

2.每一个UDP套接口都有一个接收缓冲区,到达该套接口的每个数据报都进入这个套接口接收缓冲区。当进程调用recvfrom时,缓冲区中的下一个数据报以FIFO顺序返回给进程。我们可以通过套接口选项来修改缓冲区的大小。


两个重要的函数:

#include <sys/socket.h>

ssize_t recvfrom ( int sockfd, void *buff, size_t nbytes, int flags, struct sockaddr *from, socklen_t *addrlen)

参数说明:

sockfd:标识一个已经打开的套接口描述字

buff:接收数据的缓冲区指针

nbytes:接收缓冲区的大小

flags:通常直接指定为0,也可以是图1.1中列出的一个或多个常值的逻辑或。

from:指向一个由函数返回的数据报发送者的协议地址的套接口地址结构,就是说可以通过这个参数得到发送者的一些信息

addrlen:指向一个整数的指针,该整数表示from所指向的空间的大小,可以通过sizeof来计算

返回值说明:

成功返回读写字节数,失败返回-1,除此之外,函数隐式返回了from,addrlen两个参数。


#include <sys/socket.h>

ssize_t sendto ( int sockfd, void *buff, size_t nbytes, int flags, const struct sockaddr *to, socklen_t addrlen)

参数说明:

sockfd:标识一个已经打开的套接口描述字

buff:发送数据的缓冲区指针

nbytes:发送缓冲区的大小

flags:通常直接指定为0,也可以是图1.1中列出的一个或多个常值的逻辑或。

to:指向一个数据报接收者的协议地址的套接口地址结构,就是说通过这个参数得到接受者的基本信息

addrlen:该整数表示to结构的大小,可以通过sizeof来计算

返回值说明:

成功返回读写字节数,失败返回-1


注意:

1.如果recvfrom的from参数时一个空指针,那么相应的长度参数addrlen也必须是一个空指针,表示我们并不关系数据发送者的协议地址(或者说我们不需要回复任何信息给数据发送者)。

2.recvfrom个sendto都可以用于TCP,但是通常并不这么做。

Unix网络编程之UDP实例

标签:

原文地址:http://blog.csdn.net/xiyou222/article/details/51362252

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!