C++file transfer











up vote
-1
down vote

favorite












I'm currently writing a server and client app that attemps to transfer a screenshot but it's not working properly. I implemented it like this.



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;
}
}
}
}


I call the function with this



CreateThread(0, 0, (LPTHREAD_START_ROUTINE)thread_function, 0, 0, 0);


The thing is I believe this is not a very clean way of doing it and also it's not working perfectly. After a file is received I don't correctly receive what the server is sending.



This is the server code wich I think is fine.



            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);
}


Thanks for your time and help.










share|improve this question


















  • 1




    1. threads add problems of their own, so start with removing that. 2. read this 3. once you have things working without the thread, you can consider adding it.
    – UKMonkey
    1 hour ago








  • 1




    Your receive-side check if (received == "Sending file.") is wrong. Assuming TCP, the string received can be a full 4Kb buffer, because boundaries between send calls are not preserved when calling recv. String comparison doesn't stop at the nul terminator if there is one. You should consider separating your transport layer (big lumps of data received from the TCP stream) from your parsing layer (distinguishing status or control messages from the payload).
    – Useless
    50 mins ago












  • This is indeed TCP protocol. "You should consider separating your transport layer (big lumps of data received from the TCP stream) from your parsing layer (distinguishing status or control messages from the payload)." I understand what you mean but I honestly have no idea of how to implement that. For the person who linked me "How to debug small programs" if I had an idea of why this is not working I wouldn't be asking. I don't know a lot about sockets since I just started using them. My question isn't very specific because I don't know where the problem is at all.
    – programme-zero
    40 mins ago















up vote
-1
down vote

favorite












I'm currently writing a server and client app that attemps to transfer a screenshot but it's not working properly. I implemented it like this.



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;
}
}
}
}


I call the function with this



CreateThread(0, 0, (LPTHREAD_START_ROUTINE)thread_function, 0, 0, 0);


The thing is I believe this is not a very clean way of doing it and also it's not working perfectly. After a file is received I don't correctly receive what the server is sending.



This is the server code wich I think is fine.



            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);
}


Thanks for your time and help.










share|improve this question


















  • 1




    1. threads add problems of their own, so start with removing that. 2. read this 3. once you have things working without the thread, you can consider adding it.
    – UKMonkey
    1 hour ago








  • 1




    Your receive-side check if (received == "Sending file.") is wrong. Assuming TCP, the string received can be a full 4Kb buffer, because boundaries between send calls are not preserved when calling recv. String comparison doesn't stop at the nul terminator if there is one. You should consider separating your transport layer (big lumps of data received from the TCP stream) from your parsing layer (distinguishing status or control messages from the payload).
    – Useless
    50 mins ago












  • This is indeed TCP protocol. "You should consider separating your transport layer (big lumps of data received from the TCP stream) from your parsing layer (distinguishing status or control messages from the payload)." I understand what you mean but I honestly have no idea of how to implement that. For the person who linked me "How to debug small programs" if I had an idea of why this is not working I wouldn't be asking. I don't know a lot about sockets since I just started using them. My question isn't very specific because I don't know where the problem is at all.
    – programme-zero
    40 mins ago













up vote
-1
down vote

favorite









up vote
-1
down vote

favorite











I'm currently writing a server and client app that attemps to transfer a screenshot but it's not working properly. I implemented it like this.



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;
}
}
}
}


I call the function with this



CreateThread(0, 0, (LPTHREAD_START_ROUTINE)thread_function, 0, 0, 0);


The thing is I believe this is not a very clean way of doing it and also it's not working perfectly. After a file is received I don't correctly receive what the server is sending.



This is the server code wich I think is fine.



            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);
}


Thanks for your time and help.










share|improve this question













I'm currently writing a server and client app that attemps to transfer a screenshot but it's not working properly. I implemented it like this.



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;
}
}
}
}


I call the function with this



CreateThread(0, 0, (LPTHREAD_START_ROUTINE)thread_function, 0, 0, 0);


The thing is I believe this is not a very clean way of doing it and also it's not working perfectly. After a file is received I don't correctly receive what the server is sending.



This is the server code wich I think is fine.



            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);
}


Thanks for your time and help.







c++ sockets client-server file-transfer






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 1 hour ago









programme-zero

13




13








  • 1




    1. threads add problems of their own, so start with removing that. 2. read this 3. once you have things working without the thread, you can consider adding it.
    – UKMonkey
    1 hour ago








  • 1




    Your receive-side check if (received == "Sending file.") is wrong. Assuming TCP, the string received can be a full 4Kb buffer, because boundaries between send calls are not preserved when calling recv. String comparison doesn't stop at the nul terminator if there is one. You should consider separating your transport layer (big lumps of data received from the TCP stream) from your parsing layer (distinguishing status or control messages from the payload).
    – Useless
    50 mins ago












  • This is indeed TCP protocol. "You should consider separating your transport layer (big lumps of data received from the TCP stream) from your parsing layer (distinguishing status or control messages from the payload)." I understand what you mean but I honestly have no idea of how to implement that. For the person who linked me "How to debug small programs" if I had an idea of why this is not working I wouldn't be asking. I don't know a lot about sockets since I just started using them. My question isn't very specific because I don't know where the problem is at all.
    – programme-zero
    40 mins ago














  • 1




    1. threads add problems of their own, so start with removing that. 2. read this 3. once you have things working without the thread, you can consider adding it.
    – UKMonkey
    1 hour ago








  • 1




    Your receive-side check if (received == "Sending file.") is wrong. Assuming TCP, the string received can be a full 4Kb buffer, because boundaries between send calls are not preserved when calling recv. String comparison doesn't stop at the nul terminator if there is one. You should consider separating your transport layer (big lumps of data received from the TCP stream) from your parsing layer (distinguishing status or control messages from the payload).
    – Useless
    50 mins ago












  • This is indeed TCP protocol. "You should consider separating your transport layer (big lumps of data received from the TCP stream) from your parsing layer (distinguishing status or control messages from the payload)." I understand what you mean but I honestly have no idea of how to implement that. For the person who linked me "How to debug small programs" if I had an idea of why this is not working I wouldn't be asking. I don't know a lot about sockets since I just started using them. My question isn't very specific because I don't know where the problem is at all.
    – programme-zero
    40 mins ago








1




1




1. threads add problems of their own, so start with removing that. 2. read this 3. once you have things working without the thread, you can consider adding it.
– UKMonkey
1 hour ago






1. threads add problems of their own, so start with removing that. 2. read this 3. once you have things working without the thread, you can consider adding it.
– UKMonkey
1 hour ago






1




1




Your receive-side check if (received == "Sending file.") is wrong. Assuming TCP, the string received can be a full 4Kb buffer, because boundaries between send calls are not preserved when calling recv. String comparison doesn't stop at the nul terminator if there is one. You should consider separating your transport layer (big lumps of data received from the TCP stream) from your parsing layer (distinguishing status or control messages from the payload).
– Useless
50 mins ago






Your receive-side check if (received == "Sending file.") is wrong. Assuming TCP, the string received can be a full 4Kb buffer, because boundaries between send calls are not preserved when calling recv. String comparison doesn't stop at the nul terminator if there is one. You should consider separating your transport layer (big lumps of data received from the TCP stream) from your parsing layer (distinguishing status or control messages from the payload).
– Useless
50 mins ago














This is indeed TCP protocol. "You should consider separating your transport layer (big lumps of data received from the TCP stream) from your parsing layer (distinguishing status or control messages from the payload)." I understand what you mean but I honestly have no idea of how to implement that. For the person who linked me "How to debug small programs" if I had an idea of why this is not working I wouldn't be asking. I don't know a lot about sockets since I just started using them. My question isn't very specific because I don't know where the problem is at all.
– programme-zero
40 mins ago




This is indeed TCP protocol. "You should consider separating your transport layer (big lumps of data received from the TCP stream) from your parsing layer (distinguishing status or control messages from the payload)." I understand what you mean but I honestly have no idea of how to implement that. For the person who linked me "How to debug small programs" if I had an idea of why this is not working I wouldn't be asking. I don't know a lot about sockets since I just started using them. My question isn't very specific because I don't know where the problem is at all.
– programme-zero
40 mins ago

















active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














 

draft saved


draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53266068%2fcfile-transfer%23new-answer', 'question_page');
}
);

Post as a guest





































active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes
















 

draft saved


draft discarded



















































 


draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53266068%2fcfile-transfer%23new-answer', 'question_page');
}
);

Post as a guest




















































































Popular posts from this blog

Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

ComboBox Display Member on multiple fields

Is it possible to collect Nectar points via Trainline?