【发布时间】:2018-11-12 16:13:48
【问题描述】:
我目前正在编写一个服务器和客户端应用程序,该应用程序尝试传输屏幕截图,但无法正常工作。我是这样实现的。
SOCKET sock;
char buf[4096];
DWORD WINAPI thread_function()
{
bool file_transfer = false;
bool loop = true;
while (1)
{
ZeroMemory(buf, 4096);
int bytesReceived = recv(sock, buf, 4096, 0);
if (bytesReceived > 0)
{
std::string received(buf, 0, bytesReceived);
if (received == "Sending file.")
{
file_transfer = true;
}
if (file_transfer == false)
{
std::cout << "\nSERVER> " << std::string(buf, 0, bytesReceived) << std::endl;
std::cout << "> ";
}
else if (file_transfer == true)
{
loop = true;
TCHAR *szfname = "screenshot.bmp";
FILE* f = fopen(szfname, "wb");
if (NULL == f)
{
std::cerr << "Error opening file" << std::endl;
return 1;
}
while ((bytesReceived = recv(sock, buf, 4096, 0)) > 0 && loop == true)
{
received = buf;
if (received == "File transfer completed !")
{
loop = false;
std::cout << "File transfer completed !" << std::endl;
std::cout << "> ";
}
else
{
fwrite(buf, 1, bytesReceived, f);
}
}
file_transfer = false;
}
}
}
}
我用这个调用函数
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)thread_function, 0, 0, 0);
问题是我相信这不是一种非常干净的方式,而且它也不能完美地工作。收到文件后,我没有正确接收服务器发送的内容。
这是我认为很好的服务器代码。
send(clientSocket, TEXT("Attempting to take a screenshot."), sizeof(TEXT("Attempting to take a screenshot...")), 0);
HWND win = GetDesktopWindow();
HDC dc = GetDC(win);
if (HDCToFile("screenshot.bmp", dc, { 0, 0, 1920, 1080 }) == true)
{
send(clientSocket, TEXT("Sending file."), sizeof(TEXT("Sending file.")), 0);
FILE *fp = fopen("screenshot.bmp", "rb");
if (fp == NULL)
{
std::cerr << "Error : Cannot open file." << std::endl;
return 1;
}
while (1)
{
char buff[4096] = { 0 };
int nread = fread(buff, 1, 4096, fp);
if (nread > 0)
{
send(clientSocket, buff, sizeof(buff), 0);
}
if (nread < 4096)
{
if (feof(fp))
{
std::cout << "File transfer completed !" << std::endl;
send(clientSocket, TEXT("File transfer completed !"), sizeof(TEXT("File transfer completed !")), 0);
}
if (ferror(fp))
std::cerr << "Error reading." << std::endl;
break;
}
}
}
else
{
send(clientSocket, TEXT("Screen capture failed...."), sizeof(TEXT("Screen capture failed....")), 0);
}
感谢您的时间和帮助。
【问题讨论】:
-
1.线程会添加自己的问题,所以从删除它开始。 2.阅读this 3.一旦你的东西在没有线程的情况下工作,你可以考虑添加它。
-
您的接收方检查
if (received == "Sending file.")是错误的。假设 TCP,字符串received可以是一个完整的 4Kb 缓冲区,因为在调用recv时不会保留send调用之间的边界。如果有一个,则字符串比较不会在 nul 终止符处停止。您应该考虑将传输层(从 TCP 流中接收的大量数据)与解析层(从有效负载中区分状态或控制消息)分开。 -
这确实是TCP协议。 “您应该考虑将传输层(从 TCP 流中接收的大量数据)与解析层(从有效负载中区分状态或控制消息)分开。”我明白你的意思,但老实说,我不知道如何实施。对于链接我“如何调试小程序”的人,如果我知道为什么这不起作用,我不会问。自从我刚开始使用套接字以来,我对套接字了解不多。我的问题不是很具体,因为我根本不知道问题出在哪里。
标签: c++ sockets client-server file-transfer