我已经设置了一个简单的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