We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
我做的是一个简单的文件上传下载功能,几KB的文件没有问题,超过1M的文件就出现问题了 因为if (kcp->nrcv_que < seg->frg + 1) return -1;这行代码导致调用的ikcp_recv总是返回-2,帮忙看下是怎么回事,顺便告诉我下kcp->nrcv_que与seg->frg变量的含义,谢谢
发送端代码 #include <stdio.h> #include <stdlib.h> #include "..\test.h" #include <ikcp.h> #include #include <winsock.h> #include #include #include #pragma comment(lib, "ws2_32.lib") sockaddr_in addr; int udp_send(const char *buf, int len, ikcpcb *kcp, void *user) { SOCKET sockfd = *(SOCKET *)user; sendto(sockfd, buf, len, 0, (struct sockaddr *)&addr, sizeof(addr)); return 0; } std::streampos getFileSize(const std::string &filePath) { std::ifstream file(filePath, std::ios::binary | std::ios::ate); // 以二进制模式打开并定位到文件末尾 if (!file.is_open()) { std::cerr << "Could not open the file!" << std::endl; return -1; } std::streampos fileSize = file.tellg(); // 获取文件大小 file.close(); return fileSize; } void replaceUsingRegex(std::string &str, const std::string &pattern, const std::string &replacement) { std::regex re(pattern); str = std::regex_replace(str, re, replacement); } int main() { WSADATA ws; WSAStartup(MAKEWORD(2, 2), &ws); std::string hostUrl; std::cout << "请输入服务器IP" << std::endl; std::cin >> hostUrl; addr.sin_family = AF_INET; addr.sin_port = htons(666); // 服务器端口 addr.sin_addr.s_addr = inet_addr(hostUrl.data()); // 服务器地址 int sockfd = socket(AF_INET, SOCK_DGRAM, 0); ikcpcb kcp = ikcp_create(123, (void)&sockfd); kcp->output = udp_send; ikcp_nodelay(kcp, 2, 10, 2, 1); std::string path; char data[10240]; int len = sizeof(addr); while (1) { std::cout << "请输入要上传的文件地址" << std::endl; std::cin >> path; std::cout << "正在上传中......" << std::endl; replaceUsingRegex(path,"[/]","\"); //上传文件名称与文件大小 std::string name = "[begin]"+path.substr(path.find_last_of('\')+1)+"&"+std::to_string(getFileSize(path)) +"[end]"; ikcp_send(kcp, name.data(),name.length()+1); ikcp_update(kcp, iclock()); //上传文件内容 std::ifstream inputFile(path, std::ios::binary); while (!inputFile.eof()) { // 检查是否到达文件末尾 inputFile.read(data, 10240); // 读取指定长度的字节到缓冲区 int size = inputFile.gcount(); if (size > 0) { ikcp_send(kcp, data, size); } ikcp_update(kcp, iclock()); } auto interval=iclock(); while (iclock()- interval<22222) { isleep(1); ikcp_update(kcp, iclock()); } std::cout << "上传完毕" << std::endl; } return 0; }
接收端代码 #include <stdio.h> #include <stdlib.h> #include "..\test.h" #include <ikcp.h> #include #include <winsock.h> #include #include #pragma comment(lib, "ws2_32.lib") int sockfd; // UDP 发送函数 int udp_send(const char *buf, int len, ikcpcb kcp, void user) { sockaddr_in addr = (sockaddr_in)user; sendto(sockfd, buf, len, 0, (struct sockaddr *)addr, sizeof(*addr)); return 0; } int main() { WSADATA ws; WSAStartup(MAKEWORD(2, 2), &ws); sockaddr_in server_addr, client_addr; // 创建 socket sockfd = socket(AF_INET, SOCK_DGRAM, 0); // 配置服务器地址 server_addr.sin_family = AF_INET; server_addr.sin_port = htons(666); server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); int timeout = 44444; int noTimeout = 0; // 绑定 socket bind(sockfd, (const struct sockaddr )&server_addr, sizeof(server_addr)); ikcpcb kcp = ikcp_create(123, (void)&client_addr); kcp->output = udp_send; ikcp_nodelay(kcp, 2, 10, 2, 1); int clientLen = sizeof(client_addr); char buffer[10240]; char data[10240]; std::string fileName; unsigned int fileSize; std::ofstream outputFile; std::string fileStr; char fileStrOldLen=-1; bool flag=true;//是否处于接收文件基本信息阶段 while (1) { label1: int length = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr )&client_addr, &clientLen); if (length < 0) { std::cout << "网络连接断开" << std::endl; fileStrOldLen = -1; outputFile.close(); flag = true; fileStr.clear(); continue; } ikcp_input(kcp, buffer, length); ikcp_update(kcp, iclock()); int ret = ikcp_recv(kcp, data, sizeof(data)); if (ret > 0) { if (flag) { setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char)&timeout, sizeof(timeout)); fileStr += data; auto beginIndex = fileStr.find("[begin]"); auto endIndex = fileStr.find("[end]"); if (beginIndex == -1 && endIndex == -1)//一次读不完的情况 { fileStrOldLen = fileStr.length(); goto label1; } if (fileStrOldLen == -1)//一次读完的情况 { if(endIndex+5== fileStr.length()) fileStrOldLen = fileStr.length();//一次读完并且没有读取到文件内容字节数据的情况 else fileStrOldLen = endIndex + 5;//一次读完并且有读取到文件内容字节数据的情况 } auto splitIndex = fileStr.find_first_of('&'); fileName = fileStr.substr(7, splitIndex - 7); fileSize = std::stoul(fileStr.substr(splitIndex + 1, endIndex - 1 - splitIndex)); char subtractLen = endIndex + 5 - fileStrOldLen; if (subtractLen > 0)//还存在文件内容字节数据需要写入的情况 { char allLen = ret - subtractLen; beginIndex = ret - allLen; outputFile.open(fileName, std::ios::binary); outputFile.write(&data[beginIndex], allLen); fileSize -= allLen; } fileStrOldLen = -1; fileStr.clear(); flag = false; std::cout << fileName + "正在上传......" << std::endl; } else { if (!outputFile.is_open()) outputFile.open(fileName, std::ios::binary); outputFile.write(data, ret); if ((fileSize -= ret) > 0)//接收文件内容 { goto label1; } else//接收完毕 { outputFile.close(); std::cout << fileName + "上传完毕" << std::endl; flag = true; setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char)&noTimeout, sizeof(noTimeout)); } } } } return 0; }
The text was updated successfully, but these errors were encountered:
麻烦重新好好帖下代码
Sorry, something went wrong.
我已经找到原因了
No branches or pull requests
我做的是一个简单的文件上传下载功能,几KB的文件没有问题,超过1M的文件就出现问题了
因为if (kcp->nrcv_que < seg->frg + 1) return -1;这行代码导致调用的ikcp_recv总是返回-2,帮忙看下是怎么回事,顺便告诉我下kcp->nrcv_que与seg->frg变量的含义,谢谢
发送端代码
#include <stdio.h>
#include <stdlib.h>
#include "..\test.h"
#include <ikcp.h>
#include
#include <winsock.h>
#include
#include
#include
#pragma comment(lib, "ws2_32.lib")
sockaddr_in addr;
int udp_send(const char *buf, int len, ikcpcb *kcp, void *user) {
SOCKET sockfd = *(SOCKET *)user;
sendto(sockfd, buf, len, 0, (struct sockaddr *)&addr, sizeof(addr));
return 0;
}
std::streampos getFileSize(const std::string &filePath) {
std::ifstream file(filePath, std::ios::binary | std::ios::ate); // 以二进制模式打开并定位到文件末尾
if (!file.is_open()) {
std::cerr << "Could not open the file!" << std::endl;
return -1;
}
std::streampos fileSize = file.tellg(); // 获取文件大小
file.close();
return fileSize;
}
void replaceUsingRegex(std::string &str, const std::string &pattern, const std::string &replacement) {
std::regex re(pattern);
str = std::regex_replace(str, re, replacement);
}
int main()
{
WSADATA ws;
WSAStartup(MAKEWORD(2, 2), &ws);
std::string hostUrl;
std::cout << "请输入服务器IP" << std::endl;
std::cin >> hostUrl;
addr.sin_family = AF_INET;
addr.sin_port = htons(666); // 服务器端口
addr.sin_addr.s_addr = inet_addr(hostUrl.data()); // 服务器地址
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
ikcpcb kcp = ikcp_create(123, (void)&sockfd);
kcp->output = udp_send;
ikcp_nodelay(kcp, 2, 10, 2, 1);
std::string path;
char data[10240];
int len = sizeof(addr);
while (1)
{
std::cout << "请输入要上传的文件地址" << std::endl;
std::cin >> path;
std::cout << "正在上传中......" << std::endl;
replaceUsingRegex(path,"[/]","\");
//上传文件名称与文件大小
std::string name = "[begin]"+path.substr(path.find_last_of('\')+1)+"&"+std::to_string(getFileSize(path)) +"[end]";
ikcp_send(kcp, name.data(),name.length()+1);
ikcp_update(kcp, iclock());
//上传文件内容
std::ifstream inputFile(path, std::ios::binary);
while (!inputFile.eof()) { // 检查是否到达文件末尾
inputFile.read(data, 10240); // 读取指定长度的字节到缓冲区
int size = inputFile.gcount();
if (size > 0) {
ikcp_send(kcp, data, size);
}
ikcp_update(kcp, iclock());
}
auto interval=iclock();
while (iclock()- interval<22222)
{
isleep(1);
ikcp_update(kcp, iclock());
}
std::cout << "上传完毕" << std::endl;
}
return 0;
}
接收端代码
#include <stdio.h>
#include <stdlib.h>
#include "..\test.h"
#include <ikcp.h>
#include
#include <winsock.h>
#include
#include
#pragma comment(lib, "ws2_32.lib")
int sockfd;
// UDP 发送函数
int udp_send(const char *buf, int len, ikcpcb kcp, void user) {
sockaddr_in addr = (sockaddr_in)user;
sendto(sockfd, buf, len, 0, (struct sockaddr *)addr, sizeof(*addr));
return 0;
}
int main()
{
WSADATA ws;
WSAStartup(MAKEWORD(2, 2), &ws);
sockaddr_in server_addr, client_addr;
// 创建 socket
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
// 配置服务器地址
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(666);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
int timeout = 44444;
int noTimeout = 0;
// 绑定 socket
bind(sockfd, (const struct sockaddr )&server_addr, sizeof(server_addr));
ikcpcb kcp = ikcp_create(123, (void)&client_addr);
kcp->output = udp_send;
ikcp_nodelay(kcp, 2, 10, 2, 1);
int clientLen = sizeof(client_addr);
char buffer[10240];
char data[10240];
std::string fileName;
unsigned int fileSize;
std::ofstream outputFile;
std::string fileStr;
char fileStrOldLen=-1;
bool flag=true;//是否处于接收文件基本信息阶段
while (1)
{
label1:
int length = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr )&client_addr, &clientLen);
if (length < 0)
{
std::cout << "网络连接断开" << std::endl;
fileStrOldLen = -1;
outputFile.close();
flag = true;
fileStr.clear();
continue;
}
ikcp_input(kcp, buffer, length);
ikcp_update(kcp, iclock());
int ret = ikcp_recv(kcp, data, sizeof(data));
if (ret > 0)
{
if (flag)
{
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char)&timeout, sizeof(timeout));
fileStr += data;
auto beginIndex = fileStr.find("[begin]");
auto endIndex = fileStr.find("[end]");
if (beginIndex == -1 && endIndex == -1)//一次读不完的情况
{
fileStrOldLen = fileStr.length();
goto label1;
}
if (fileStrOldLen == -1)//一次读完的情况
{
if(endIndex+5== fileStr.length()) fileStrOldLen = fileStr.length();//一次读完并且没有读取到文件内容字节数据的情况
else fileStrOldLen = endIndex + 5;//一次读完并且有读取到文件内容字节数据的情况
}
auto splitIndex = fileStr.find_first_of('&');
fileName = fileStr.substr(7, splitIndex - 7);
fileSize = std::stoul(fileStr.substr(splitIndex + 1, endIndex - 1 - splitIndex));
char subtractLen = endIndex + 5 - fileStrOldLen;
if (subtractLen > 0)//还存在文件内容字节数据需要写入的情况
{
char allLen = ret - subtractLen;
beginIndex = ret - allLen;
outputFile.open(fileName, std::ios::binary);
outputFile.write(&data[beginIndex], allLen);
fileSize -= allLen;
}
fileStrOldLen = -1;
fileStr.clear();
flag = false;
std::cout << fileName + "正在上传......" << std::endl;
}
else
{
if (!outputFile.is_open()) outputFile.open(fileName, std::ios::binary);
outputFile.write(data, ret);
if ((fileSize -= ret) > 0)//接收文件内容
{
goto label1;
}
else//接收完毕
{
outputFile.close();
std::cout << fileName + "上传完毕" << std::endl;
flag = true;
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char)&noTimeout, sizeof(noTimeout));
}
}
}
}
return 0;
}
The text was updated successfully, but these errors were encountered: