UDP编程-QT-VC

UDP编程

一: socket编程中的几种地址

    Socket编程会遇到三种地址, 都是定义的结构体(struct):

    Struct in_addr
    {
        Unsigned int s_addr;
    }
    这是一个IPv4地址,在IPv4的报文中,源地址和目的地址用32bit表示。通常定义在netinet/in.h中。

    Struct sockaddr
    {
        Unsigned short sa_family;
        Char sa_data[14]; 
    };
    这就是一个socket地址, 不论什么使用socket的调用都须要这样的格式的地址,所以我们能够看到大部分程序在这里都进行了一个强制转换。
    sa_family表示地址类型,通常为AF_UNIX或者是AF_INET;
    sa_data[14],存储地址信息,比方IP地址,port号等等。
    sockaddr通常定义在bits/socket.h文件里

    因为sockaddr这个地址不太easy分析,因此就用了一种easy分析的地址来表示sockaddr, 这就是sockaddr_in产生的原因,通常sockaddr_in定义于netinet/in.h文件里
    Struct sockaddr_in{
        Unsigned short sa_family;
        Unsigned short sin_port;
        Struct in_addr sin_addr;
        Unsigned char sin_zero[8];
    };
    Sa_family表示地址类型,与sockaddr的sa_family相应
    Sin_port表示端口号
    Sin_addr表示IP地址
    Sin_zero[8]用于零填充,使得sockaddr_in和sockaddr可以转换。在使用sockaddr_in时,必须用bzero()或memset()把这个数组所有清零。

二: UDP Socket编程

UDP是不保证数据正确传输的协议,它不过对IP协议进行了简单的封装(添加了port),所以要保证传输数据的正确性须要程序猿自己来处理。UDP相对于TCP的一个优点就是没有建立连接时的开销,这样两个端点之间没有就必要维持连接。
UDP Socket编程比TCP要简单的多。下面是UDP的编程步骤:

第1步:向内核申请套接字,使用socket()函数,这是不论什么socket编程的第1步。
第2步,绑定socket地址(也适用于TCP),对于server端是必须的,对于client是可选的。使用bind()函数。Bind的实质是将socket与本地地址绑定。本地地址主要指IP和port。对于一个主机来说,bind的主要意义在于绑定port。由于本地地址是知道的,通过试验,发现仅仅有绑定的地址仅仅能为 0.0.0.0或者本机的IP地址才有效。否则,指定一个网络地址(注意这个词),会导致收发数据不正常,不论什么一个可能成为client的IP地址都不能被绑 定。所谓的本地地址,即是如此。所以说bind的真正意义在于绑定port。对于UDPclient来说,假设不用bind,那么OS会自己主动分配一个当前已用port 号+1的port供其暂时使用。
第3步,数据传输。对于UDP来说,由于没有建立连接,所以并不知道发送数据的目的地址,这就须要在send使指定目的地址,所以用sendto(), 当然也能够在第3部之前调用connect()进行一下连接,但对于UDP来说,不过记录对方的地址,这样就能够在发数据时不用指定地址(用 send()), 使用recv/recvfrom收数据,这两个函数的差别只在于,recvfrom会记录对方的socket地址,recvfrom有一个easy出错的地 方,就是关于from地址的长度,在调用时这个长度必须是结构体struct sockaddr的长度,由于在recvfrom的实现中将会用到这个值。Recv/send中的flag假设是0,那么这两个函数等同于read /write. 须要注意的是,系统的socket缓冲区中并没有对收到的数据作字符串式的结尾处理,所以分析报文须要时须要用到recv/recvfrom返回的实际读 取长度。
第4步,结束,使用close()关闭套接字。

正如前文所述,socket编程会遇到3种地址,事实上仅仅须要记住:全部的系统调用均使用sockaddr这样的地址。

int sendto(int sockfd, const void *msg,int len,unsigned int flags,const struct sockaddr *to, int tolen);
该函数比send()函数多了两个參数,to表示目地机的IP地址和port号信息,而tolen经常被赋值为sizeof (struct sockaddr)。Sendto 函数也返回实际发送的数据字节长度或在出现发送错误时返回-1。
int recvfrom(int sockfd,void *buf,int len,unsigned int flags,struct sockaddr *from,int *fromlen);
from是一个struct sockaddr类型的变量,该变量保存源机的IP地址及port号。fromlen常置为sizeof(struct sockaddr)。当recvfrom()返回时,fromlen包括实际存入from中的数据字节数。Recvfrom()函数返回接收到的字节数或 当出现错误时返

三:创建用于通讯的Socket类

    #include "winsock.h"

    //UDPclient发送错误回调函数,回调函数能够通过自己定义消息更新页面
    typedef void (CALLBACK* ONUDPERROR)(void*,int nErrorCode);
    //UDPclient接收数据回调函数
    typedef void (CALLBACK* ONUDPRECV)(v

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值