【发布时间】:2015-09-01 06:01:46
【问题描述】:
我想用 C++ 定期从客户端向服务器发送一个文件。 比如说,每 10 秒一次。 send.txt 是我想通过套接字发送到服务器的文件
send.txt 在前 10 秒内包含“123456”。 我通过添加 78910 11 12 更改文件内容,使其变为“123456 78910 11 12”
服务器应在接下来的 10 秒内收到“123456 78910 11 12”。但问题是我收到的文件仍然是原始文件(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 文件 收到按任意键继续...
客户:
套接字已连接...文件打开正常! ... 成功 ... 发送完成 ... 成功 ... 发送完成 ... 成功 ... 发送完成 ... 成功...发送完成...成功...发送完成...
我是这样用的
定期发送文件,但结果不是我想要的。
我希望你能帮助我。谢谢。我真的很感谢你的帮助。
【问题讨论】:
-
问题在于,在服务器端,您读取某个文件的大小,然后每次客户端连接时接收到那么多字节。只要客户端发送一些数据,您就需要继续阅读。
-
你能举个例子吗?
-
请避免在同一行写多个语句,这样会让人难以阅读,也容易漏掉。
-
它是特定于操作系统的。 Linux 有inotify(7)。您可以定期运行
rsync -
请修正你的缩进...这几乎是不可读的。