2012-08-24 23 views
6

Trong C Tôi đã có mã số làm việc nhưng không biết tại sao nó hoạt động, vì vậy tôi bắt đầu viết lại nó để tôi thực sự có thể hiểu những gì đang xảy ra.Làm thế nào để lưu trữ đầu ra của recv()?

Cho đến nay rất tốt! Tôi viết lại và chắc chắn 90% tôi hiểu mọi thứ đang diễn ra; vấn đề tuy nhiên, là tôi không có ý tưởng làm thế nào để lưu trữ các dữ liệu chunk nhận được recv (databff) vào bộ đệm được phân bổ trước của tôi (htmlbff).

Xét đoạn mã sau (lưu ý rằng tôi lột này xuống khá một chút, vì vậy nó chỉ bao gồm những điều cơ bản, ví dụ như không có việc tái phân bổ bộ nhớ hoặc rò rỉ bảo vệ, vv ...):

#define BUFFERSIZE 4096 
#define MAXDATASIZE 256 

char *htmlbff, databff[MAXDATASIZE]; 
int c, i = BUFFERSIZE, q = 0;   
if(!(htmlbff = malloc(i))) 
{ 
    printf("\nError! Memory allocation failed!"); 
    return 0x00; 
} 
while((c = recv(sock, databff, MAXDATASIZE, 0)) > 0) 
{ 
    /*memory checks stripped out since they are irrelevent for this post*/ 
    /*store data to the appropriate area in htmlbff*/ 
    q += c;   
} 

Vì vậy (nếu c là kích thước của đoạn dữ liệu hiện tại, và q là tổng số dữ liệu nhận được cho đến nay (q được tăng thêm c mỗi lần lặp lại vòng lặp). Tại thời điểm này tôi đang sử dụng q để xử lý bộ nhớ (trong trường hợp ai đó đang tự hỏi) nhưng tôi tin rằng nó cũng sẽ có mục đích trong giải pháp cho vấn đề này.

Ở bất kỳ mức nào, câu hỏi tôi hỏi là liên quan đến nhận xét thứ hai. Làm cách nào để lưu trữ dữ liệu từ recv thành htmlbff chính xác?

Trả lời

2

Sử dụng memcpy, và bù đắp htmlbff bởi q:

memcpy(htmlbff + q, databff, c); 

Bạn có thể tương tự recv trực tiếp vào htmlbff:

c = recv(sock, htmlbff + q, MAXDATASIZE, 0)); 

Nhưng nó là tốt để giữ một bộ đệm riêng, và tùy thuộc vào mã đầy đủ của bạn , nó có thể làm cho mọi việc rõ ràng hơn.

Hãy chắc chắn rằng bạn thêm séc vào BUFFERSIZE để bạn không sao chép qua các giới hạn của htmlbff. Bạn đã đề cập rằng bạn đã loại bỏ việc xử lý realloc, vì vậy có thể bạn đã xử lý việc này.

tên liên tục của bạn là một chút bối rối, khi bộ đệm dữ liệu tôi sẽ sử dụng BUFFERSIZE để chỉ ra kích thước của mỗi đoạn, ví dụ: kích thước của databff.

+0

Tôi thực sự thích câu trả lời này cảm ơn bạn. Tôi thấy điều này hữu ích nhất vì bây giờ tôi có thể bỏ qua bằng cách sử dụng bộ đệm và viết trực tiếp vào htmlbff. –

5

Sử dụng memcpy() để sao chép (nối thêm) dữ liệu vào htmlbff nhưng bạn cũng cần đảm bảo bạn không vượt quá kích thước htmlbff. Ngừng ngừng nhận dữ liệu khi bạn nhận được BUFFERSIZE byte hoặc sử dụng realloc() để mở rộng htmlbff để chứa nhiều dữ liệu hơn.

Ví dụ:

char* htmlbff; 
size_t htmlbff_size = BUFFERSIZE; 
htmlbff = malloc(htmlbff_size); 

if (htmlbff) 
{ 
    while((c = recv(sock, databff, MAXDATASIZE, 0)) > 0) 
    { 
     if (c + q > htmlbff_size) 
     { 
      htmlbff_size *= 2; /* Arbitrary doubling of size. */ 
      char* tmp = realloc(htmlbff, htmlbff_size); 
      if (tmp) 
      { 
       htmlbff = tmp; 
      } 
      else 
      { 
       /* memory allocation failure. */ 
       free(htmlbff); 
       htmlbff = 0; 
       break; 
      } 
     } 
     memcpy(htmlbff + q, databff, c); 
     q += c; 
    } 
} 
+0

Rất đẹp, cảm ơn bạn, và đó chính xác là cách tôi quản lý bộ nhớ của mình, ngoại trừ việc tôi đã thêm một bước khác để chỉ thực hiện kích thước của bộ đệm với chính xác số byte tôi cần khi kết thúc vòng lặp. Một lần nữa cảm ơn bạn đã trả lời. –

1

Bạn cần phải giữ cho việc phân bổ lại/mở rộng bộ đệm để phù hợp với tất cả các dữ liệu (nếu các dữ liệu đọc ra khỏi ổ cắm vượt MAXDATASIZE) = Bằng cách đó như recv đọc dữ liệu vào databff, htmlbff của bạn có thể phát triển trong bộ nhớ và sau đó đọc mới có thể được nối vào htmlbff tổng thể của bạn.

q và c giống như con trỏ để theo dõi bạn đang ở đâu và bạn phải đi bao xa.

memcpy(htmlbff+q, databff, c); //Do this in your whle loop to append the data 
2

gì tôi sẽ làm là recv() dữ liệu trực tiếp vào htmlbff, trừ khi bạn cần để làm chế biến thêm về nó.

Hãy chắc chắn rằng bạn realloc()htmlbff khi i - q là ít hơn MAXDATASIZE để luôn có chỗ cho recv() khác.

Sau đó, bạn sẽ gọi recv(sock, htmlbff + q, MAXDATASIZE, 0)