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

UDP通信

时间:2015-05-12 08:05:48      阅读:110      评论:0      收藏:0      [点我收藏+]

标签:

UDP和TCP的对比。
  –UDP处理的细节比TCP少。
  –UDP不能保证消息被传送到目的地。
  –UDP不能保证数据包的传递顺序。
  –TCP处理UDP不处理的细节。
  –TCP是面向连接的协议。
  –UDP是无连接协议。
  –TCP保持一个连接。
  –UDP只是把数据发送出去而已。
 
 
TCP的优点
  –TCP提供以认可的方式显示的创建连接和终止连接。
  –TCP保证可靠的,顺序的以及不会重复的数据传输。
  –TCP处理流控制。
  –TCP允许数据优先。
  –如果数据没有传送到,TCP套接字会返回出错提示。
  –TCP通过保持连接并将数据块分成更小的分片来处理大数据,而无需程序员编码处理。
TCP的缺点
  –TCP需要创建并保持一个连接,给系统带来很大开销。
  –TCP数据传输效率低
 
UDP的优点
  –UDP不要求保持一个连接。
  –UDP没有因接收方没有收到数据包重传而带来开销。
  –设计UDP的目的是用于短应用和控制消息。
  –在一个数据包接一个数据包基础上,UDP要求的网络带宽比TCP小。
UDP的缺点
  –程序员必须创建代码监测数据包的正确性,必要时重传。
  –程序员必须把大数据包分片。
 
 
选择使用哪一种协议?
  –一些消息重要程度不高,或者有规律重复,可以使用UDP。
  –如果要传输一个重要的数据,丢失一点就会破坏整个数据,那么需要选择TCP。
  –telnet,ssh,http等基本都基于TCP。
  –流媒体为了保证很窄的网络带宽来传送更多的数据,基本采用UDP。
  –多数游戏中,丢失来自某个用户的状态更新可能不会引起注意,所以采用UDP。
  –设计用在局域网的应用可以采用UDP,因为在局域网中丢失数据包的可能性很低。
 
使用UDP与TCP所用的代码基本类似,唯一的区别在于socket函数调用的时候的一个参数的不同。

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

参数type为SOCK_STREAM代表TCP,SOCK_DGRAM代表UDP。
对于TCP和UDP都可以使用recvfrom函数,但recv只能TCP使用。
 
 
使用UDP发送数据。

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

UDP不需要握手机制,也不需要确认另一个系统是否有服务端在listen。
 
 
UDP发送数据例子
int main(int arg, char *args[])
{
    int st = socket(AF_INET, SOCK_DGRAM, 0);
    if (st == -1)
    {
        printf("socket failed %s\n", strerror(errno));
        return 0;
    }
    int on = 1;
    if (setsockopt(st, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) == -1)
    {
        printf("setsockopt failed %s\n", strerror(errno));
        return EXIT_FAILURE;
    }
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(8080);
    addr.sin_addr.s_addr = inet_addr(args[1]);
    char buf[1024];
    while (1)
    {
        memset(buf, 0, sizeof(buf));
        read(STDIN_FILENO, buf, sizeof(buf));
        if (sendto(st, buf, strlen(buf), 0, (struct sockaddr *) &addr,
                sizeof(addr)) == -1)
        {
            printf("sendto failed %s\n", strerror(errno));
            break;
        }
    }
    close(st);
    return EXIT_SUCCESS;
}
 
使用UDP接收数据。

ssize_t recvfrom(int s, void *buf, size_t len, int flags,

  struct sockaddr *from, socklen_t *fromlen);

UDP不需要listen,bind之后就可以接收数据了。
 
 
UDP接收数据例子
int main(void)
{
    int st = socket(AF_INET, SOCK_DGRAM, 0);
    if (st == -1)
    {
        printf("socket failed %s\n", strerror(errno));
        return 0;
    }
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(8080);
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    if (bind(st, (struct sockaddr *)&addr, sizeof(addr)) == -1)
    {
        printf("bind failed %s\n", strerror(errno));
        return -1;
    }
    char buf[1024];
    struct sockaddr_in client_addr;
    socklen_t len = sizeof(client_addr);
    while(1)
    {
        memset(&client_addr, 0, sizeof(client_addr));
        memset(buf, 0, sizeof(buf));
        if(recvfrom(st, buf, sizeof(buf), 0,
                (struct sockaddr *)&client_addr, &len) == -1)
        {
            printf("recvfrom failed %s\n", strerror(errno));
            break;
        }else
        {

            printf("%s recv is %s\n", inet_ntoa(client_addr.sin_addr), buf);
        }
    }
    close(st);
    return 0;
}

 

 

 

UDP通信

标签:

原文地址:http://www.cnblogs.com/shichuan/p/4496314.html

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