我注意到有一个C ++和C#的内置函数,但是C没有。 (我在Windows机器上)。
所以我写了这两个函数,但它们没有工作,它们只是卡住了(我怀疑它是发送一个,因为当客户端接收时他只是根据函数返回值得到错误)。
以下是功能(服务器和客户端之间的套接字工作正常,我已经测试过了):
int recvFile(SOCKET s, const char* file_path)
{
FILE* fp = fopen(file_path, "wb");
char* file_buf = malloc(sizeof(char)*PACKAGE_LEN); //so it will be 0
int bytesRecieved, bytesWritten;
if(!fp)
{
fclose(fp);
free(file_buf);
return 1;
}
do
{
bytesRecieved = recv(s, file_buf, PACKAGE_LEN, 0); //receiving that file buffer in the size of PACKAGE_LEN (maximum chunk size).
if(bytesRecieved != PACKAGE_LEN)
{
fclose(fp);
free(file_buf);
return 1; //if there's an error...
}
if(!charPresent(file_buf, PACKAGE_LEN, EOF)) //as long as there's no EOF character in the file buffer received now.
{
fwrite(file_buf, sizeof(char), PACKAGE_LEN, fp); //write to file normally.
}
}
while(!charPresent(file_buf, PACKAGE_LEN, EOF)); // do it as long there's no EOF in the file buffer.
fwrite(file_buf, sizeof(char), indexOf(file_buf, PACKAGE_LEN, EOF), fp); //the last time you write the file buffer including the EOF is outside the loop.
fclose(fp);
free(file_buf);
return 0;
}
int charPresent(const char* str, size_t size, char ch)
{
int i;
for(i = 0 ; i < size ; i++)
{
if(str[i] == ch)
{
return 1;
}
}
return 0;
}
int indexOf(const char* str, size_t size, char ch)
{
int i;
for(i = 0 ; i < size ; i++)
{
if(str[i] == ch)
{
return i;
}
}
return -1;
}
(在功能charPresent()
和IndexOf
方面犯错的地方不多 - 我没有故意使用strlen()
,因为\0
不是答应在那个缓冲区里)。和...
int sendFile(SOCKET s, const char* file_path)
{
FILE* fp = fopen(file_path, "rb");
int i, err = 0, bytesSent, isOk = 1;
char* file_buf = malloc(sizeof(char)*PACKAGE_LEN);
char ch = 0;
if(!fp)
{
fclose(fp);
free(file_buf);
return 1;
}
while(ch != EOF && isOk)
{
i = 0;
do
{
do
{
err = ((fread(&ch, sizeof(char), 1, fp)) != 1);
file_buf[i] = ch;
}
while(err); //keep reading until read successfully.
i++;
if(i == PACKAGE_LEN) //means we achieved the maximum chunk size.
{
isOk = 0; //to exit the inner loop.
}
}
while(ch != EOF && isOk);
bytesSent = send(s, file_buf, PACKAGE_LEN, 0); //sending the file buffer over the socket.
if(bytesSent != PACKAGE_LEN)
{
fclose(fp);
free(file_buf);
return 1; //return an error (it is taken care of later on).
}
isOk = 1; // so the loop won't stop because we achieved only one chunk.
}
fclose(fp);
free(file_buf);
return 0;
}
我做错了什么? :P
我想到了一个替代方案,它只是为了找出文件的长度和循环FILE_LEN/PACKAGE_LEN + ((!(FILE_LEN%PACKAGE_LEN))?(0):(1))
而在上一次运行中只发送一个带有EOF但是基本上它是相同的概念,我认为。
答案 0 :(得分:2)
你的代码真的无法挽救。你应该诚实地重新开始。
在编写任何代码之前,请查看使用TCP的其他协议的某些协议规范。您可以查看FTP,HTTP,SMTP等。
特别注意他们如何划分邮件。请记住,TCP是一种字节流协议 - 它不会保留消息边界。
我强烈建议你去编写规范。这样,如果您的代码不起作用,您可以确定哪一方不符合规范。 (如果它们都是,并且它仍然无法工作,那么规范就会被破坏。)否则,没有办法弄清楚错误是什么,因为没有任何陈述。什么是对的。
此外,您无法以这种方式使用EOF
。没有代表文件末尾的字符。每个可能的字符值都可以包含在文件中。没有&#34;额外&#34;可能意味着&#34;文件结尾的字符&#34;。