我想用C ++定期从客户端发送文件到服务器。 比如,每10秒钟。 send.txt是我想通过socket
发送给服务器的文件send.txt包含" 123456"前10秒。 我通过添加78910 11 12来更改文件内容,因此它变为" 123456 78910 11 12"
服务器应该收到" 123456 78910 11 12"接下来的10秒钟。但问题是我收到的文件仍然是原始文件(123456),看起来它永远不会改变。
这是我的客户代码:
#include "stdafx.h"
#include <WinSock2.h>
#include <Windows.h>
#include <stdio.h>
#include <iostream>
#include <chrono>
#include <thread>
#include <functional>
SOCKET clientsock; WSADATA winsock; sockaddr_in serverAddr , addr; int Addrlen = sizeof(serverAddr); FILE *File; unsigned long Size; char
*Buffer;
void startClient() {
WSAStartup(MAKEWORD(2,2), &winsock);
if(LOBYTE(winsock.wVersion) != 2 || HIBYTE(winsock.wVersion) != 2 ){
WSACleanup();
}
clientsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr("127.0.0.1"); addr.sin_port = htons(6091);
connect(clientsock,(sockaddr*)&addr,sizeof(addr));
printf("socket connected... \n");
//preparing the file
File = fopen("B:\\send.txt","rb");
if(!File) {
printf("",WSAGetLastError()); }
printf("File open ok ! \n");
fseek(File,0,SEEK_END); Size = ftell(File); fseek(File,0,SEEK_SET);
char cisi[10]; sprintf(cisi, "%i",Size);
send(clientsock,cisi,10,0); // file size sent
/* Buffer = (char*) malloc (Size+1) ; fread(Buffer,Size,1,File); fclose(File);
send(clientsock,Buffer,Size,0); //File binary sent free(Buffer); printf("sending finished ... \n"); */
}
void timer_start(std::function<void(void)> func, unsigned int interval) {
std::thread([func, interval]() {
while (true)
{
func();
std::this_thread::sleep_for(std::chrono::milliseconds(interval));
}
}).detach(); }
void sending() {
File = fopen("B:\\send.txt","rb"); fseek(File,0,SEEK_END); Size = ftell(File); fseek(File,0,SEEK_SET); printf("Success...\n");
Buffer = (char*) malloc (Size+1) ; fread(Buffer,Size,1,File); fclose(File);
send(clientsock,Buffer,Size,0); //File binary sent free(Buffer); printf("sending finished ... \n");
}
int _tmain(int argc, _TCHAR* argv[]) {
startClient();
timer_start(sending, 10000);
while(true);
//sending();
//Sleep(5000);
system("PAUSE"); return 0;
}
,服务器代码是
#include "stdafx.h"
#include <WinSock2.h>
#include <Windows.h>
#include <iostream>
#include <chrono>
#include <thread>
#include <functional>
SOCKET servsocket, ClientAcc;
WSAData winsock;
sockaddr_in addr,incomingAddress;
int addrlen = sizeof(sockaddr_in);
int addresslen = sizeof(incomingAddress);
char *Filesize = new char[10];
int Size = 0;
char *Buffer = new char[Size];
FILE *File;
void start_p() {
//socket initialization
WSAStartup(MAKEWORD(2,2), &winsock);
//socket check
if(LOBYTE(winsock.wVersion) !=2 || HIBYTE(winsock.wVersion) != 2 ) {
WSACleanup();
}
servsocket = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP);
addr.sin_family = AF_INET;
addr.sin_port = htons(6091);
bind(servsocket, (sockaddr*)&addr, sizeof(addr));
listen(servsocket, 5);
ClientAcc = accept(servsocket, (sockaddr*)&incomingAddress, &addresslen);
char *ClientIP = inet_ntoa(incomingAddress.sin_addr);
int ClientPort = ntohs(incomingAddress.sin_port);
printf("Client Connected ... \n");
printf("IP : %s:%d\n", ClientIP, ClientPort);
//receive file size
recv(ClientAcc,Filesize,10,0);
Size = atoi((const char*)Filesize);
printf("File size : %d\n",Size);
}
void timer_start(std::function<void(void)> func, unsigned int interval)
{
std::thread([func, interval]() {
while (true)
{
func();
std::this_thread::sleep_for(std::chrono::milliseconds(interval));
}
}).detach();
}
void receive() {
Buffer = (char*)malloc(Size+1);
int file_dit, total_file = 0 ;
while(total_file < Size) {
ZeroMemory(Buffer,Size);
if((file_dit = recv(ClientAcc,Buffer,Size,0)) < 0 ){
goto END;
} else {
total_file += file_dit;
File = fopen("B:\\fileReceived.txt", "wb");
fwrite((const char*)Buffer,1,file_dit,File);
fclose(File);
Sleep(1000);
}
END:
printf("File received ... \n");
free(Buffer);
closesocket(ClientAcc);
WSACleanup();
getchar();
}
}
int _tmain(int argc, _TCHAR* argv[])
{
start_p();
timer_start(receive, 10000);
//receive();
//Sleep(5000);
system("PAUSE");
return 0;
}
我用这种方式,输出为:
服务器:
客户端连接... IP:127.0.0.1:15425文件大小:20文件 收到任何按键继续......
客户:
连接套接字......文件打开确定! ......成功......发送完毕 ......成功......发送完毕......成功......发送完毕...... 成功......发送完成......成功......发送完毕......
定期发送文件,但结果不是我想要的。
我希望你能帮助我。谢谢。我非常感谢你的帮助。
答案 0 :(得分:0)
在关闭文件之前,文件的内容实际上并未写入磁盘。我认为你在添加文本时保持文件打开,你需要在客户端再次阅读之前将其关闭。
fclose(file); // Here is when the content is written to disk.
此外,发送后你没有关闭文件。
所以,每次对文件(句柄)执行操作时,都应该在启动另一个之前将其关闭。
真正的错误必须是,你总是读到char cisi[10]
并且它只有10个空格,你只发送10个字符。 send(clientsock,cisi,10,0);
更改行:
// ...
char cisi[10];
// ...
send(clientsock,cisi,10,0);
为:
// ...
char *cisi = new char[Size];
// ...
send(clientsock,cisi,Size,0);
关于服务器端代码:
recv(ClientAcc,Filesize,10,0);
使用上面的代码行,你总能得到10个字符。但在这里你不知道客户有多少个字符。
对此的基本解决方案是首先发送该号码(在文件之前),这样您就会知道为了完成接收操作你必须阅读的字符。
完整的解决方案涉及某些协议的实施。或者使用更高级的库(例如boost.Asio)。
建议:
使用fstream管理文件。毕竟,你是用c ++编写的。 ; d