【发布时间】:2018-03-26 21:19:40
【问题描述】:
所以最近为了一个课程项目,我决定自己做一个程序,可以通过局域网传输文件并将其集成到 linux 操作系统中(在这种情况下,我所做的只是将它添加到上下文菜单中)使用套接字服务器。
它的工作方式本质上是,
Server is waiting.
Client connects.
Client sends a message of 1024 length with the first 4 characters reserved
The first 4 characters are used to store an int which will state the length of the message
server recieves them, writes them, then waits for the next block
when the server recieves a message where the length is 0
it ends the transfer and closes the files
这完美地适用于文本文件。由于有用的反馈,我对我最后的代码进行了改进,我设法创建了操作系统实际识别文件扩展名的东西,无论类型如何。但是对于像 pngs 这样的东西,它们会显示为黑色,而对于 exe,它们会立即出现段错误。
无论文件类型如何,我可以在读写方面进行哪些更改以使其正常工作?我不知道该去哪里,因为我应该工作
附加信息:我正在使用 C 进行编码。要打开文件,我使用 fopen、fgetc 和 fputc。 这是我的服务器代码的一个尝试:
while (1){
n = read(newsockfd,message,1024);
if (n < 0) {
fclose(fptr2);
error("ERROR reading from socket");
}
//The first 4 bytes/characters are used to store the length.
//I read them by getting a pointer to the first char and then reading it as
//an int by casting it. This works with no problem
char *p=&message;
int *p2=(int*)p;
int length=*p2;
//Checks if the length is 0, if so, exit
if (length==0)
break;
//writes to the file
for (int i=4;i<length;i++){
fputc(message[i], fptr2);
}
n = write(newsockfd,"Ready",5);
if (n < 0)
error("ERROR writing to socket");
bzero(message,255);
}
fclose(fptr2);
//n = write(newsockfd,"I got your message",18);
//if (n < 0) error("ERROR writing to socket");
printf("Done.\n");
return 0;
}
从我的客户端执行,读取文件然后发送。
while (finished!=0&&c!=EOF)
{
for (int i =4;i<1024;i++)
{
if (c==EOF)
{
char* p=&message;
int* pi=(int*)p;
*pi=i;
finished=0;
//printf("length is:%d\n",i);
break;
}
//printf("%c",c);
message[i]=c;
//fputc(c, fptr2);
c = fgetc(fptr1);
}
if (finished!=0)
{
char* p=&message;
int* pi=(int*)p;
*pi=1024;
}
n = write(sockfd,message,1024);
if (n < 0)
{
fclose(fptr1);
error("ERROR writing to socket");
}
bzero(message,1024);
//reading
n = read(sockfd,buffer,255);
if (n < 0)
error("ERROR reading from socket");
}
【问题讨论】:
-
可执行文件中有很多 NUL 字符,所以你需要重新考虑你的设计。另请注意,
NUL是一个零字符,通常写为'\0',与NULL不同,后者是一个零指针。 -
EOF 是一个条件。不是字符也不等于NULL
-
发送文件数据前先发送文件大小。发送和接收文件大小指示的字节数,而不管文件字节实际是什么
-
使用
fopen()时,将模式设置为二进制"b"。这在 Linux 上不会有什么不同,但如果你跨平台(尤其是 Windows),那么它可以。