I’m facing a problem with write function not working properly if it placed inside a loop with out sleep.what i’m trying to achieve is to transfer files from local machine to a remote FTP server the following code works fine but the write function not transferring the bytes properly it transfer only of the half bytes, it works fine with sleep blocks the loop.
struct sockaddr_in
{
int16_t sin_family;
uint16_t sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
struct in_addr
{
uint32_t s_addr;
};
struct sockaddr_in servaddr;
memset(&servaddr, 0, sizeof(servaddr));
int isocket = socket(AF_INET,SOCK_STREAM,0);
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("some ip goes here");
servaddr.sin_port = htons(21);
char buf[1024];
int MAX_LENGTH = 1024;
char readBuf[MAX_LENGTH];
long cmd;
int res = connect(isocket, (struct sockaddr_in *)&servaddr, sizeof(servaddr));
if(res < 0) {
NSLog(@"problem connecting to server");
}
recv(isocket, (void *)readBuf,MAX_LENGTH, 0);
NSLog(@"response: %s",readBuf);
NSLog(@"Issuing command");
strcpy(buf, "USER foo\r\n");
cmd = send(isocket, (void *)buf, strlen(buf), 0); //send username
recv(isocket, (void *)readBuf,MAX_LENGTH, 0);
NSLog(@"response: %s",readBuf); //read response
strcpy(buf, "PASS *******\r\n");
cmd = send(isocket, (void *)buf, strlen(buf), 0);//send password
recv(isocket, (void *)readBuf, MAX_LENGTH, 0);
NSLog(@"response: %s",readBuf); //read response
strcpy(buf, "CWD /httpdocs/testing\r\n");
cmd = send(isocket, (void *)buf, strlen(buf), 0);//send directory
recv(isocket, (void *)readBuf, MAX_LENGTH, 0);
NSLog(@"response: %s",readBuf); //read response
strcpy(buf, "TYPE I\r\n");
cmd = send(isocket, (void *)buf, strlen(buf), 0);//set transfer type
recv(isocket, (void *)readBuf, MAX_LENGTH, 0);
NSLog(@"response: %s",readBuf); //read response
strcpy(buf, "PASV\r\n");
cmd = send(isocket, (void *)buf, strlen(buf), 0);//set transfer mode to passive
recv(isocket, (void *)readBuf, MAX_LENGTH, 0);
NSLog(@"response: %s",readBuf); //read response
NSString *pasvResponse = [NSString stringWithFormat:@"%s",readBuf];
strcpy(buf, "STOR mmov.jpeg\r\n");
cmd = send(isocket, (void *)buf, strlen(buf), 0);//start tranfering files
pasvResponse = [pasvResponse stringByReplacingOccurrencesOfString:@"227 Entering Passive Mode (" withString:@""];
pasvResponse = [pasvResponse stringByReplacingOccurrencesOfString:@")." withString:@""];
pasvResponse = [pasvResponse stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSArray *matches = [pasvResponse componentsSeparatedByString:@","];
NSString *ip = nil;
int port = 0;
if([matches count] > 2) {
ip = [NSString stringWithFormat:@"%@.%@.%@.%@",matches[0],matches[1],matches[2],matches[3]];
port = ([matches[4] intValue] * 256) + ([matches[5] intValue]);
}
if(port != 0 && ip != nil) {
struct sockaddr_in servaddr_pasv;
memset(&servaddr_pasv, 0, sizeof(servaddr_pasv));
int isocket_pasv = socket(AF_INET,SOCK_STREAM,0);
servaddr_pasv.sin_family = AF_INET;
servaddr_pasv.sin_addr.s_addr = inet_addr([ip UTF8String]);
servaddr_pasv.sin_port = htons(port);
int res_pasv = connect(isocket_pasv, (struct sockaddr_in *)&servaddr_pasv, sizeof(servaddr_pasv));
if(res_pasv < 0) {
NSLog(@"problem connecting to server passv");
}
NSInputStream *input = [NSInputStream inputStreamWithFileAtPath:@"/Users/myMac/Desktop/limitation.jpeg"];
[input open];
int i= 0;
while(1) {
if([input hasBytesAvailable]) {
i++;
uint8_t buffer[1024];
long res = [input read:buffer maxLength:1024];
NSLog(@"Bytes Read: %ld",res);
if(res != 0) {
long bytesSent = write(isocket_pasv, buffer, sizeof(buffer));
NSLog(@"%d Bytes Transfered: %ld",i,bytesSent);
// sleep(1);
}
if(res == 0) {
break;
}
}
}
[input close];
NSLog(@"bytes write completed");
close(isocket_pasv);
}
close(isocket);
Any help Thanks in advance.
You can’t guarantee you can offload your entire buffer in one go. You’ll have to loop over write until all your data is transferred. You should also check for errors returned by write, it’s likely to be the place where you catch all kinds of network related events as well as more typical O/S write errors.