使用readDataToLength:方法时从服务器套接字读取的数据不完整

时间:2019-02-04 16:44:29

标签: ios objective-c asyncsocket gcdasyncsocket cocoaasyncsocket

我正在使用cocoaAsyncSocket库开发用于iOS和OSX的Web代理,但遇到了问题。我能够接受来自客户端的多个连接,解析标头,通过端口80/443连接到目标,并开始接收数据,同时将数据传递回客户端套接字。但是,我遇到的问题是,使用方法readDataToLength:x时,在完成读取内容之前,服务器套接字似乎已关闭,但是,如果我只使用readDataWithTimeout,则一切正常,并且页面将加载。

使用curl通过我的代理服务器,我可以看到部分接收了数据,但是连接通过

关闭
transfer closed with 12 bytes remaining to read
* stopped the pause stream!
* Closing connection 0
curl: (18) transfer closed with 12 bytes remaining to read

但是委托方法

socket:(GCDAsyncSocket *)sock didReadPartialDataOfLength:(NSUInteger)partialLength tag:(long)tag

告诉我它已经完成了12字节的部分读取,因此读取似乎已经完成。

-(void)socket:(GCDAsyncSocket *)sock didReadPartialDataOfLength:(NSUInteger)partialLength tag:(long)tag {
    NSLog(@"READ PARTIAL DATA %lu with tag: %lu",partialLength, tag);
    [sock readDataToLength:partialLength withTimeout:3 tag:tag];
}
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
    ConnectionData *socketData;
    @synchronized (self) {
        socketData = [self getConnectionDataForSocket:sock];
    }
    if (tag == CLIENT_SOCK_READ) {
        //NSLog(@"READ FROM CLIENT");
        if (!socketData.serverSocket){
            //We dont have a server socket yet, assume that we are reading the header data.

            NSString *headers = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];

            //Decide if we have a http or ssl connection
            if ([headers containsString:@"CONNECT"]) {
                //TLS SESSION
                NSString* hostToConnect = [self extractStringFromString:headers from:@"CONNECT " to:@":"];
                NSError *connectError;
                GCDAsyncSocket *serverSock = [[GCDAsyncSocket alloc]initWithDelegate:self delegateQueue:[self socketsDispatchQueue]];
                @synchronized (self) {
                    socketData.serverSocket = serverSock;
                }
                if (![serverSock connectToHost:hostToConnect onPort:443 withTimeout:10 error:&connectError]){
                    NSLog(@"Failed to connect to host: %@", [connectError debugDescription]);
                }
                NSString *tlsClientResponse = @"HTTP/1.0 200 Connection established\r\n\r\n";
                [[socketData clientSocket]writeData:[tlsClientResponse dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:CLIENT_SOCK_WRITE];
            } else {
                NSString *hostToConnect = [self extractStringFromString:headers from:@"http://" to:@"/"];
                NSString *newheaderLine = [self prepareHttpHeader:headers];

                //Rewite headers
                NSError *connectError;
                GCDAsyncSocket *serverSock = [[GCDAsyncSocket alloc]initWithDelegate:self delegateQueue:[self socketsDispatchQueue]];

                @synchronized (self) {
                    socketData.serverSocket = serverSock;
                }
                if (![serverSock connectToHost:hostToConnect onPort:80 withTimeout:10 error:&connectError]){
                    NSLog(@"Failed to connect to host: %@", [connectError debugDescription]);
                }
                [socketData.serverSocket writeData:[newheaderLine dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:false] withTimeout:10 tag:SERVER_SOCK_WRITE];
            }
        } else {
            [socketData.serverSocket writeData:data withTimeout:3 tag:SERVER_SOCK_WRITE];
        }

    } else if (tag == SERVER_SOCK_READ){
        [socketData.serverSocket readDataToLength:25 withTimeout:3 tag:SERVER_SOCK_READ];
        [socketData.clientSocket writeData:data withTimeout:3 tag:CLIENT_SOCK_WRITE];
    }

}

-(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag
{
    ConnectionData *socketData;
    @synchronized (self) {
        socketData = [self getConnectionDataForSocket:sock];
    }
    if (tag == SERVER_SOCK_WRITE){
        [socketData.serverSocket readDataToLength:25 withTimeout:3 tag:SERVER_SOCK_READ];
    } else if (tag == CLIENT_SOCK_WRITE){
        [socketData.clientSocket readDataToLength:25 withTimeout:3 tag:CLIENT_SOCK_READ];
        [socketData.serverSocket readDataToLength:25 withTimeout:3 tag:SERVER_SOCK_READ];


    }
}

如果有人可以将我指向正确的方向,我会非常感激!

0 个答案:

没有答案