您的位置:首页 > 产品设计 > UI/UE

使用posix_quic-master传输文件

2019-06-10 09:20 639 查看

首先修改原函数的客户端

#include "quic_socket.h"
#include "debug.h"
#include <string.h>
#include <stdio.h>
#include <string>
#include <sys/epoll.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <assert.h>

using namespace posix_quic;

#define CHECK_RES(res, api) \
do {\
if (res < 0) {\
perror(api " error");\
return 1;\
}\
} while (0)

bool gIsTestReset = false;
bool gIsTestSocketReset = false;
bool gIsTestSocketResetWithStream = false;

QuicSocket conn = -1;

void onStreamClose() {
if (gIsTestSocketReset) {
QuicCloseSocket(conn);
}
}

int doLoop(QuicEpoller ep) {
struct epoll_event evs[1024];//
//收集epoll事件中已经发送的事件
int n = QuicEpollWait(ep, evs, sizeof(evs)/sizeof(struct epoll_event), 6000);
//检查n的返回值
CHECK_RES(n, "epoll_wait");

int res;
for (int i = 0; i < n; i++) {
struct epoll_event & ev = evs[i];
int fd = ev.data.fd;
EntryCategory category = GetCategory(fd);//判断监听事件种类

UserLog("QuicEpoller trigger: fd = %d, category = %s, events = %s",
fd, EntryCategory2Str((int)category), EpollEvent2Str(ev.events));

if (ev.events & EPOLLOUT) {
// connected
UserLog("Connected.\n");

if (category == EntryCategory::Socket) {
QuicStream stream = QuicCreateStream(fd);//创建stream流
assert(stream > 0);

struct epoll_event ev;
ev.data.fd = stream;
ev.events = EPOLLIN;
//将stream加入到ep中去
res = QuicEpollCtl(ep, EPOLL_CTL_ADD, stream, &ev);
CHECK_RES(res, "epoll_ctl");
//将hello quic这几个字符串写入到sstream流中去
//  std::string s = "Hello quic!";
char r_file[]="/home/IPcom/Downloads/posix_quic-master/test/client/test.txt";
FILE *r_ptr=NULL;
r_ptr= fopen(r_file,"rb");
if(r_ptr == NULL)
{
printf("error");
return 0;
}
char buffer[1024];
int length=0;
while(!feof(r_ptr))
{
length=fread(buffer,1,1024,r_ptr);//128
}

res = QuicWrite(stream, buffer, length, false);
CHECK_RES(res, "write");
}
}

/**       if (ev.events & EPOLLIN) {//如果是读事件
UserLog("QuicDebugInfo:\n%s\n", GlobalDebugInfo(src_all).c_str());

if (category == EntryCategory::Socket) {//判断是否client连接
// client needn't accept
} else if (category == EntryCategory::Stream) {//判断是否是stream事件
// stream, recv data.
char buf[10240];
res = QuicRead(fd, buf, sizeof(buf));//读事件
CHECK_RES(res, "read");

UserLog("recv(len=%d): %.*s\n", res, res, buf);
//bool gIsTestSocketResetWithStream = false;
//QuicSocket conn = -1;
if (gIsTestSocketResetWithStream)
QuicCloseSocket(conn);
else if (std::string(buf, res) != "Bye") {//如果没有输入bye
std::string s = "Bye";
//bool gIsTestReset = false;
if (gIsTestReset) {
res = QuicWrite(fd, s.c_str(), s.size(), false);
CHECK_RES(res, "write");
QuicCloseStream(fd);
onStreamClose();
} else {
res = QuicWrite(fd, s.c_str(), s.size(), true);
CHECK_RES(res, "write");
}
}
}
}
*/
if (ev.events & EPOLLERR) {
if (category == EntryCategory::Socket) {
UserLog("Close Socket fd=%d\n", fd);
QuicCloseSocket(fd);
} else if (category == EntryCategory::Stream) {
UserLog("Close Stream fd=%d\n", fd);
QuicCloseStream(fd);
onStreamClose();
}
}
}

return 0;
}

int main() {
//uint64_t debug_mask = 0;  64位无符号数
//enum posix_quic::eDbgMask::dbg_all = 4294967295L
//enum posix_quic::eDbgMask::dbg_timer = 1024L
debug_mask = dbg_all & ~dbg_timer;
// 真正的epoll fd, 可用poll、epoll监听
// typedef int QuicEpoller;
//返回epoll句柄
QuicEpoller ep = QuicCreateEpoll();
//判断表达式是否是真
assert(ep >= 0);
//创建一个udp套接字
QuicSocket socket = QuicCreateSocket();
assert(socket > 0);
conn = socket;

int res;
//初始化地址
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(9700);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
//建立udp连接
res = QuicConnect(socket, (struct sockaddr*)&addr, sizeof(addr));
assert(errno == EINPROGRESS);
assert(res == -1);
//告诉内核要监听什么事件
struct epoll_event ev;
ev.data.fd = socket;
ev.events = EPOLLIN | EPOLLOUT;//输入输出事件
//将socket套接字加入到ep
res = QuicEpollCtl(ep, EPOLL_CTL_ADD, socket, &ev);
//判断res是否大于0

CHECK_RES(res, "epoll_ctl");

for (;;) {
res = doLoop(ep);
if (res != 0)
return res;
}
}

这里我们使用一些文件操作的函数

char r_file[]="/home/IPcom/Downloads/posix_quic-master/test/client/test.txt";
FILE *r_ptr=NULL;
r_ptr= fopen(r_file,"rb");
if(r_ptr == NULL)
{
printf("error");
return 0;
}
char buffer[1024];
int length=0;
while(!feof(r_ptr))
{
length=fread(buffer,1,1024,r_ptr);//128
}

这篇博客介绍了fopen函数 可以参考一下
添加链接描述
fread()函数在这篇博客中得以介绍添加链接描述
下面附上服务器端

#include "quic_socket.h"
#include "debug.h"
#include <string.h>
#include <stdio.h>
#include <string>
#include <sys/epoll.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <assert.h>
#include <fstream>
using namespace posix_quic;

#define CHECK_RES(res, api) \
do {\
if (res < 0) {\
perror(api " error");\
return 1;\
}\
} while (0)

int OnRead(QuicStream fd) {
int res;
char buf[10240];
for (;;) {
res = QuicRead(fd, buf, sizeof(buf));
if (res < 0) {
if (errno == EAGAIN)
return 0;

QuicCloseStream(fd);
return 1;
} else if (res == 0) {
QuicStreamShutdown(fd, SHUT_WR);
return 1;
}

UserLog("recv(len=%d): %.*s\n", res, res, buf);
std::ofstream   OsWrite("test.txt",std::ofstream::app);
OsWrite<<buf;
OsWrite<<std::endl;
OsWrite.close();
res = QuicWrite(fd, buf, res, false);CHECK_RES(res, "write");
}

}

int doLoop(QuicEpoller ep, QuicSocket listenSock) {
struct epoll_event evs[1024];
int n = QuicEpollWait(ep, evs, sizeof(evs)/sizeof(struct epoll_event), 6000);
CHECK_RES(n, "epoll_wait");

int res;
for (int i = 0; i < n; i++) {
struct epoll_event & ev = evs[i];
int fd = ev.data.fd;
EntryCategory category = GetCategory(fd);

UserLog("QuicEpoller trigger: fd = %d, category = %s, events = %s",
fd, EntryCategory2Str((int)category), EpollEvent2Str(ev.events));

if (ev.events & EPOLLOUT) {
// 此次测试中, 协议栈5MB的缓冲区足够使用, 不再创建额外的用户层缓冲区.
UserLog("Ignore EPOLLOUT\n");
}

if (ev.events & EPOLLIN) {
if (category == EntryCategory::Socket) {
if (fd == listenSock) {
// accept socket
//                    UserLog("QuicDebugInfo:\n%s\n", GlobalDebugInfo(src_all).c_str());
for (;;) {
QuicSocket newSocket = QuicSocketAccept(fd);
if (newSocket > 0) {
struct epoll_event ev;
ev.data.fd = newSocket;
ev.events = EPOLLIN;
res = QuicEpollCtl(ep, EPOLL_CTL_ADD, newSocket, &ev);
CHECK_RES(res, "epoll_ctl");

UserLog("Accept Socket fd=%d, newSocket=%d\n", fd, newSocket);
} else {
UserLog("No Accept Socket. fd=%d\n", fd);
break;
}
}
} else {
// accept stream
for (;;) {
QuicStream newStream = QuicStreamAccept(fd);
if (newStream > 0) {
struct epoll_event ev;
ev.data.fd = newStream;
ev.events = EPOLLIN;
res = QuicEpollCtl(ep, EPOLL_CTL_ADD, newStream, &ev);
CHECK_RES(res, "epoll_ctl");
UserLog("Accept Stream fd=%d, newSocket=%d\n", fd, newStream);
OnRead(newStream);

} else {
UserLog("No Accept Stream. fd=%d\n", fd);
break;
}
}
}

} else if (category == EntryCategory::Stream) {
// stream, recv data.
OnRead(fd);
}
}

if (ev.events & EPOLLERR) {
if (category == EntryCategory::Socket) {
UserLog("Close Socket fd=%d\n", fd);
QuicCloseSocket(fd);
} else if (category == EntryCategory::Stream) {
UserLog("Close Stream fd=%d\n", fd);
QuicCloseStream(fd);
}
}
}

return 0;
}

int main() {
debug_mask = dbg_all & ~dbg_timer;

Q在这里插入片uicEpoller ep = QuicCreateEpoll();
assert(ep >= 0);

QuicSocket socket = QuicCreateSocket();
assert(socket > 0);

int res;

struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(9700);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");

res = QuicBind(socket, (struct sockaddr*)&addr, sizeof(addr));
CHECK_RES(res, "bind");

struct epoll_event ev;
ev.data.fd = socket;
ev.events = EPOLLIN | EPOLLOUT;
res = QuicEpollCtl(ep, EPOLL_CTL_ADD, socket, &ev);
CHECK_RES(res, "epoll_ctl");

for (;;) {
res = doLoop(ep, socket);
if (res != 0)
return res;
}
}

读取并存放文件使用的是这一步骤

std::ofstream   OsWrite("test.txt",std::ofstream::app);
OsWrite<<buf;
OsWrite<<std::endl;
OsWrite.close();
res = QuicWrite(fd, buf, res, false);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: