gpt4 book ai didi

objective-c - 服务器/客户端无法正确通信(CocoaAsyncSocket)

转载 作者:行者123 更新时间:2023-12-03 18:00:41 26 4
gpt4 key购买 nike

我有一个简单的客户端和服务器应用程序半与 CocoaAsyncSocket 一起使用。我可以使用客户端连接到服务器,并且可以在它们之间来回传递数据,并且委托(delegate)方法似乎可以正确触发。我的问题是我只能将数据发送回传递给委托(delegate)方法之一的 (AsyncSocket *) 对象。当接受连接时,我将套接字添加到 NSMutableArray 中,但稍后如果我尝试使用套接字写入失败。所以

[connectedSockets addObject:newSocket];
//then later
[[connectedSockets objectAtIndex:i] writeData:someData withTimeout:-1 tag:0];

不起作用。服务器和客户端的代码如下。初始通信确实有效,但是当我的通知被调用时,即使 NSLog 语句测试数组中的套接字并获取正确的 IP 地址和端口,也不会发送任何数据:

服务器:

- (id)init
{
self = [super init];
if (self) {
listenSocket = [[AsyncSocket alloc] initWithDelegate:self];
[listenSocket setRunLoopModes:[NSArray arrayWithObject:NSRunLoopCommonModes]];
[listenSocket acceptOnPort:42381 error:nil];


connectedSockets = [[NSMutableArray alloc] init];
newNotificationDictArray = [[NSMutableArray alloc] init];
updateNotificationDictArray = [[NSMutableArray alloc] init];

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(newJobNotification:)
name:@"NewJob"
object:nil];
}

return self;

}

-(void)onSocketDidDisconnect:(AsyncSocket *)sock
{
[connectedSockets removeObject:sock];
}

- (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err
{
[connectedSockets removeObject:sock];
}

- (void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket
{
[connectedSockets addObject:newSocket];
}


- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
{
if ([newNotificationDictArray count] > 0) {
NSMutableData *data = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver encodeObject:newNotificationDictArray forKey:@"DictArray"];
[archiver finishEncoding];
[archiver release];
[sock writeData:data withTimeout:-1 tag:0];
[data release];
}

[sock readDataWithTimeout:-1 tag:0];
}

- (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag
{
[sock readDataWithTimeout:-1 tag:0];
}

- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
[sock readDataWithTimeout:-1 tag:0];
}

-(void) newJobNotification: (NSNotification *) notification
{
NSDictionary *dict = [notification userInfo];
[newNotificationDictArray addObject:dict];
[updateNotificationDictArray addObject:dict];
NSMutableData *updateData = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:updateData];
[archiver encodeObject:updateNotificationDictArray forKey:@"DictArray"];
[archiver finishEncoding]
[updateNotificationDictArray removeAllObjects];
[archiver release];
NSLog(@"Attempting to write to %@:%i", [[connectedSockets objectAtIndex:0] connectedHost], [[connectedSockets objectAtIndex:0] connectedPort])
[[connectedSockets objectAtIndex:0] writeData:updateData withTimeout:-1 tag:0];
}

然后是客户端:

- (id)init
{
self = [super init];
if (self) {
socket = [[AsyncSocket alloc] initWithDelegate:self];
}
return self;
}

-(void) connectToHost: (NSString *) address
{

}

-(BOOL)onSocketWillConnect:(AsyncSocket *)sock
{
[sock retain];
[socket readDataWithTimeout:-1 tag:0];
return YES;
}

-(void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
{
NSLog(@"Did Connect on port %i", [sock connectedPort]);
}

-(void) disconnectFromRemoteHost
{
[socket disconnect];
}

-(void)onSocketDidDisconnect:(AsyncSocket *)sock
{
NSLog(@"Did Disconnect");
}

- (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err
{
NSLog(@"Disconnect Error: %@", [err localizedDescription]);
}

- (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag
{
[socket readDataWithTimeout:-1 tag:0];
}

- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
NSArray *dictArray = [[unarchiver decodeObjectForKey:@"DictArray"] retain];
[unarchiver finishDecoding];
[unarchiver release];
for (NSDictionary *dict in dictArray) {
if ([[dict objectForKey:@"Kind"] isEqualTo:@"New"])
[[NSNotificationCenter defaultCenter] postNotificationName:@"NewJob" object:self userInfo:dict];
else if ([[dict objectForKey:@"Kind"] isEqualTo:@"Update"])
[[NSNotificationCenter defaultCenter] postNotificationName:@"JobUpdate" object:self userInfo:dict];
}
[socket readDataWithTimeout:-1 tag:0];
}

帮助我 stackoverflow,你是我唯一的希望!

最佳答案

我发现您发布的代码有两个潜在问题。第一个似乎不太可能引起您的问题,但无论如何我都会发布它。在您的客户端代码中,您有:

-(BOOL)onSocketWillConnect:(AsyncSocket *)sock 
{
[sock retain];
[socket readDataWithTimeout:-1 tag:0];
return YES;
}

我不确定你为什么要在这里保留“sock”。您已经拥有创建的套接字的保留副本,这似乎可能会导致泄漏。

至于第二个问题,这更有可能是导致你失败​​的原因,我认为这是正在发生的事情。查看 AsyncSocket 的文档,我看到了这一点:

However, AsyncSocket is not thread-safe. You must only invoke methods on AsyncSocket from the thread/runloop on which the socket is configured. If you find yourself on a thread which is different from the thread on which AsyncSocket is running, and you need to invoke a method on AsyncSocket, then you must use a method like performSelector:onThread: to ensure the method is invoked on AsyncSocket's thread (and thereby maintaining thread-safety).

您接收通知并触发“稍后”写入的代码可能在另一个线程中,因此即使该线程有效,写入也无法执行您期望的操作。如果您想要线程安全,AsyncSocket 文档继续建议您使用 GCDAsyncSocket。

关于objective-c - 服务器/客户端无法正确通信(CocoaAsyncSocket),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7153906/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com