我已經設置了一個簡單的TCP文件傳輸。除了收到的文件大小比發送的文件更小以外,一切似乎都正常工作。接收文件的大小似乎沒有任何模式。TCP連接似乎接收不完整的數據
(在下面的代碼,注意典型的客戶機/服務器輥相反) 我的客戶端代碼是這樣的:
#define kMaxBacklog (5)
// fill out the sockadd_in for the server
struct sockaddr_in servAdddress;
//memcpy() to fill in the sockaddr
//setup the socket
int sockd, returnStatus;
sockd = socket(AF_INET, SOCK_STREAM, 0);
if (sockd == -1)
NSLog(@"could not create client socket");
else
NSLog(@"created client socket");
returnStatus = connect(sockd, (struct sockaddr*)&servAdddress, sizeof(servAdddress));
if (returnStatus == -1)
NSLog(@"could not connect to server - errno:%i", errno);
else
NSLog(@"connected to server");
NSData *dataWithHeader = [self getDataToSend];
returnStatus = send(sockd, [dataWithHeader bytes], [dataWithHeader length], 0);
if (returnStatus == -1)
NSLog(@"could not send file to server");
else if(returnStatus < [dataWithHeader length])
NSLog(@"ONLY PARTIAL FILE SENT");
else
NSLog(@"file sent of size: %i", returnStatus);
shutdown(sockd, SHUT_WR);
close(sockd);
客戶端方法總是報告它發送整個文件。
對於服務器:
#define MAXBUF (10000)
int _socket;
_socket = socket(AF_INET, SOCK_STREAM, 0); // set up the socket
struct sockaddr_in addr;
bzero(&addr, sizeof(addr));
addr.sin_len = sizeof(addr);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(0);
int retval = bind(_socket, (struct sockaddr *)&addr, sizeof(addr));
if (retval == -1)
NSLog(@"server could not bind to socket");
else
NSLog(@"server socket bound");
socklen_t len = sizeof(addr);
retval = getsockname(_socket, (struct sockaddr *)&addr, &len);
if (retval == -1)
NSLog(@"server could not get sock name");
else
NSLog(@"server socket name got");
int socket1, socket2, clientAddrLen, returnStatus;
struct sockaddr_in servAdddress, clientAddress;
clientAddrLen = sizeof(servAdddress);
socket1 = _socket;
returnStatus = listen(socket1, kMaxBacklog);
if (returnStatus == -1)
NSLog(@"server could not listen on socket");
else
NSLog(@"server socket listening");
while(1){
FILE *fd;
int i, readCounter;
char file[MAXBUF];
NSLog(@"server blocking on accept()");
socket2 = accept(socket1, (struct sockaddr*)&clientAddress, (socklen_t*)&clientAddrLen);
if (socket2 == -1)
NSLog(@"server could not accpet the connection");
else
NSLog(@"server connection accepted");
i = 0;
readCounter = recv(socket2, file, MAXBUF, 0);
if(!readCounter)
NSLog(@"server connection cancelled, readCount = 0");
else if (readCounter == -1){
NSLog(@"server could not read filename from socket");
close(socket2);
continue;
}
else
NSLog(@"server reading file of size: %i", readCounter);
fd = fopen([myfilePathObject cStringUsingEncoding:NSASCIIStringEncoding], "wb");
if(!fd){
NSLog(@"server could not open the file for creating");
close(socket2);
continue;
}
else
NSLog(@"server file open for creating");
returnStatus = fwrite([myData bytes], 1, [myData length], fd);
if (returnStatus == -1)
NSLog(@"Error writing data to server side file: %i", errno);
else
NSLog(@"file written to disk);
readCounter = 0;
//close (fd);
returnStatus = fclose(fd);
if(returnStatus)
NSLog(@"server error closing file");
所以零星的readCounter變量將不包含大小爲所發送的文件,但有些時候也一樣。
如果重要的是在iPhone和iPhone模擬器之間進行文件傳輸,無論是通過WIFI。無論手機是服務器還是仿真器是服務器,都會發生這種情況。
如果有人能幫助我理解爲什麼會發生這種情況,我會很感激。我認爲TCP的全部目的是爲了避免這種問題。
(給予信貸,這是因爲,對於我的服務器和我沉重借用從書客戶端代碼:權威指南Linux網絡編程,戴維斯,特納和Yocom從Apress出版)
我相信這本書一定處理部分正確讀取! – janm 2009-12-03 03:33:29