您的位置:首页 > 其它

UDT源码剖析(二):UDT自带例程recvfile注释

2012-09-19 17:16 489 查看
#ifndef WIN32

#include <arpa/inet.h>

#include <netdb.h>

#else

#include <winsock2.h>

#include <ws2tcpip.h>

#endif

#include <fstream>

#include <iostream>

#include <cstdlib>

#include <cstring>

#include <udt.h>

using namespace std;

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

{

if ((argc != 5) || (0 == atoi(argv[2])))

{

cout << "usage: recvfile server_ip server_port remote_filename local_filename" << endl;

return -1;

}

// use this function to initialize the UDT library

// 初始化UDT库

UDT::startup();

// 地址信息提示、目标的地址信息指针

struct addrinfo hints, *peer;

// 内存初始化,全部置为0,设置同sendfile

memset(&hints, 0, sizeof(struct addrinfo));

hints.ai_flags = AI_PASSIVE;

hints.ai_family = AF_INET;

hints.ai_socktype = SOCK_STREAM;

// 创建一个本地Socket

UDTSOCKET fhandle = UDT::socket(hints.ai_family, hints.ai_socktype, hints.ai_protocol);

// 根据传入参数和地址信息提示创建目标地址信息

if (0 != getaddrinfo(argv[1], argv[2], &hints, &peer))

{

cout << "incorrect server/peer address. " << argv[1] << ":" << argv[2] << endl;

return -1;

}

// connect to the server, implict bind

// 连接到服务器,第一个参数为Socket,第二个为连接地址,第三个为地址长度(底层用来判断是否符合IPv4、IPv6标准的长度)

if (UDT::ERROR == UDT::connect(fhandle, peer->ai_addr, peer->ai_addrlen))

{

cout << "connect: " << UDT::getlasterror().getErrorMessage() << endl;

return -1;

}

// 释放通过getaddrinfo分配的地址信息

freeaddrinfo(peer);

// send name information of the requested file

// 发送请求的文件名称

int len = strlen(argv[3]);

// 向目标发送文件名的长度

// 第一个参数为Socket,第二个参数为数据地址,第三个参数为数据长度,第四个参数会被底层忽略,没有意义

if (UDT::ERROR == UDT::send(fhandle, (char*)&len, sizeof(int), 0))

{

cout << "send: " << UDT::getlasterror().getErrorMessage() << endl;

return -1;

}

// 向目标发送文件名

// 第一个参数为Socket,第二个参数为数据地址,第三个参数为数据长度,第四个参数会被底层忽略,没有意义

if (UDT::ERROR == UDT::send(fhandle, argv[3], len, 0))

{

cout << "send: " << UDT::getlasterror().getErrorMessage() << endl;

return -1;

}

// get size information

// 接收文件大小

int64_t size;

// 接收一个文件大小数据,内容为一个int64_t值,长度为int64_t的长度,数值保存在size中

// 第一个参数为Socket,第二个参数为数据保存地址,第三个参数为数据长度,第四个参数底层会忽略,没有意义

if (UDT::ERROR == UDT::recv(fhandle, (char*)&size, sizeof(int64_t), 0))

{

cout << "send: " << UDT::getlasterror().getErrorMessage() << endl;

return -1;

}

// 负值表示没有该文件

if (size < 0)

{

cout << "no such file " << argv[3] << " on the server\n";

return -1;

}

// receive the file

// 开始接收文件

// 通过二进制方式写入文件,如果文件已存在则覆盖

fstream ofs(argv[4], ios::out | ios::binary | ios::trunc);

// 接收到的数据大小以及偏移量

int64_t recvsize;

int64_t offset = 0;

// 从0位置开始接收文件数据

// 第一个参数为Socket,第二个参数为文件流,第三个参数为偏移量,第四个参数为文件大小

if (UDT::ERROR == (recvsize = UDT::recvfile(fhandle, ofs, offset, size)))

{

cout << "recvfile: " << UDT::getlasterror().getErrorMessage() << endl;

return -1;

}

// 关闭连接Socket

UDT::close(fhandle);

// 关闭文件流

ofs.close();

// use this function to release the UDT library

// 释放UDT库

UDT::cleanup();

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: