Wednesday, 15 February 2012

c - strange situation: sending file from server -



c - strange situation: sending file from server -

i have code send file server client. thing client correctly receives file size server, file (jpeg image), recreated right file size on client side, when open image displayed half correctly, half corrupted.

here relevant parts of code. thought why can happening?

server:

while(1) { printf("waiting take connections \n"); connfd = accept(listenfd, (struct sockaddr*)null, null); read_file("/users/macbookair/documents/server/server/file1.jpeg", buffer, &length); // send write(connfd, &length, 4); // length, 110193 bytes write(connfd, buffer, length); // file close(connfd); sleep(1); }

client:

// open file file * ptrmyfile = fopen("/users/macbookair/documents/client/client/file1.jpeg","wb"); if(null == ptrmyfile) { printf("unable open file \n"); homecoming 1; } int size = 0; read(sockfd, &size, 4); // read length first read(sockfd, buffer, size); // file printf("fsize %d\n", size); // create file fwrite(buffer, size, 1, ptrmyfile); fclose(ptrmyfile);

buffer of sufficient length. find weird right number of bytes received, image half correctly displayed.

network programming not programming local files.

read(sockfd, &size, 4); // read length first read(sockfd, buffer, size); // file

you ignoring homecoming value of read() -- which, critically, tells how many bytes read. since network operation, might fewer bytes asked for. means first 2 bytes of size might read, , have inquire 1 time again next 2 bytes. unlikely, possible. file split chunks if larger few k.

int read_full(int sock, size_t sz, void *buffer) { size_t pos = 0; while (pos < sz) { size_t request_amt = sz - pos; ssize_t result = read(sock, (char *) buffer + pos, request_amt); if (result < 0) { // if eintr, read() interrupted // in case, have seek 1 time again // otherwise, error occurred if (errno != eintr) homecoming -1; } else if (result > 0) { pos += result; } else { // unexpected eof homecoming -1; } } homecoming 0; }

in practice, if send big amount of info on tcp connection, split chunks , transmitted on period of time. have little command on how big chunks are.

here corrected code, assert() lazy error checking:

uint32_t size; int r; r = read_full(sockfd, sizeof(size), &size); assert(r == 0); void *data = malloc(size); assert(data != null); r = read_full(sockfd, size, data); assert(r == 0);

important note: write() / send() also can partial writes, need write same loop on server!

c

No comments:

Post a Comment