GCDAsyncSocket服务器仅在第一次接收数据

客户端每次按下发送button都会发送消息,而服务器只会在第一次接收消息。 服务器有什么问题

服务器:

- (void)viewDidLoad { [super viewDidLoad]; asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()]; NSError *err = nil; if (![asyncSocket acceptOnPort:10000 error:&err]){ NSLog(@"Error in acceptOnPort:error: -> %@", err); } } - (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket { NSLog(@"Accepted new socket from %@:%hu", [newSocket connectedHost], [newSocket connectedPort]); self.asyncSocket = newSocket; NSString *welcomMessage = @"Hello from the server\r\n"; [self.asyncSocket writeData:[welcomMessage dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:1]; [self.asyncSocket readDataWithTimeout:-1 tag:0]; } -(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{ NSString *msg = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"MSG: %@",msg); } 

客户:

 - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()]; [socket setDelegate:self]; } -(IBAction)connectToServer { NSError *err = nil; if (![socket connectToHost:self.txtIp.text onPort:10000 error:&err]) // Asynchronous! { // If there was an error, it's likely something like "already connected" or "no delegate set" NSLog(@"I goofed: %@", err); return; } } - (void)socket:(GCDAsyncSocket *)sender didConnectToHost:(NSString *)host port:(UInt16)port { NSLog(@"Cool, I'm connected! That was easy."); [socket readDataWithTimeout:-1 tag:0]; } - (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag { if (tag == 1) NSLog(@"First request sent"); else if (tag == 2) NSLog(@"Second request sent"); } - (void)socket:(GCDAsyncSocket *)sender didReadData:(NSData *)data withTag:(long)tag { NSLog(@"Received Data: %@",data); } -(void)sendMessage { NSData *msg = [self.txtMsg.text dataUsingEncoding:NSUTF8StringEncoding]; NSLog(@"Data Send: %@",msg); [socket writeData:msg withTimeout:-1 tag:1]; } 

您必须在didReadData: delegate中从您的服务器类进行读取调用。 rest很好。 使用下面的代码。

 -(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag { [sock readDataWithTimeout:-1 tag:0]; NSString *msg = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"MSG: %@",msg); } 

所以经过这一番努力之后,我想出了以下消化数据的模式。 虽然以下是简单化的过程,但它很容易移植到不同的任务上:

 Somewhat Swift Solution var dataCache = Data() func socket(_ sock: GCDAsyncSocket, didConnectToHost host: String, port: UInt16) { sock.readData(withTimeout: -1, tag: 0) } func socket(_ sock: GCDAsyncSocket, didRead data: Data, withTag tag: Int) { dataCache.append(data) sock.readData(withTimeout: -1, tag: 0) } func socketDidDisconnect(_ sock: GCDAsyncSocket, withError err: Error?) { print("Closed with error: \(err)") processData() } func socketDidCloseReadStream(_ sock: GCDAsyncSocket) { print("Closed successfully") processData() } func processData() { // Do something with dataCache eg print it out: print("The following read payload:\(String(data:dataCache, encoding: .utf8) ?? "Read data invalid")") dataCache = Data() }