[英]Read the characters of an executable for file transfers in C
因此,最近在一個課程項目中,我決定為自己創建一個程序,該程序可以使用套接字在局域網上傳輸文件並將其集成到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
這完美地適用於文本文件。 由於提供了有用的反饋意見,我對上一個代碼進行了改進,因此我設法創建了一種操作系統可以實際識別文件擴展名的東西,而與類型無關。 但是,對於png之類的東西,它們顯示為黑色;對於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");
}
0x00是二進制文件的有效字符,因此當您看到一個字符時就不能“停止” [就像您可以為字符串一樣]。
您將數據包的第一個字符用作EOF標記(即非零表示有效數據,零表示EOF)。 但是,請注意,數據包中的第一個數據字符可能為零,因此您必須使用一個不包含數據字符的字節“ header”,而僅使用“ stop”標志char [如果您願意]:
while (1) {
// Reading
n = read(newsockfd, message, 1023);
if (n < 0) {
fclose(fptr2);
error("ERROR reading from socket");
}
// Checks if the first character is null, if so, exit
if (message[0] == 0)
break;
// writes to the file
// NOTE: now the data starts at offset 1!
int i = 1;
for (; i < n; ++i) {
fputc(message[i], fptr2);
}
i = 0;
n = write(newsockfd, "Ready", 5);
if (n < 0)
error("ERROR writing to socket");
bzero(message, 1023);
}
fclose(fptr2);
但是,一種更簡單的方法是只讀取直到長度返回零:
while (1) {
// Reading
n = read(newsockfd, message, 1024);
// end of data
if (n == 0)
break;
// error
if (n < 0) {
fclose(fptr2);
error("ERROR reading from socket");
}
// writes to the file
fwrite(message,1,n,fptr2);
i = 0;
n = write(newsockfd, "Ready", 5);
if (n < 0)
error("ERROR writing to socket");
bzero(message, 1023);
}
fclose(fptr2);
簡而言之,要使此功能生效,最重要的更改是在程序停止讀取時進行更改。 EOF只是-1,在文本文件中,這沒問題,但是在其他文件中,此值可能在任何地方都可以找到。 為了正確讀取字符,您必須首先獲取文件長度,然后簡單地讀取字符直到達到該長度。
fseek(fptr1, 0L, SEEK_END);
int sz = ftell(fptr1);
rewind(fptr1);
int count=0;
while (count!=sz)
{
//other code left out for simplicity
c = fgetc(fptr1);
count++;
}
進行此更改后,我的程序可以正常運行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.