首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用NSNetService连接到服务器但失败-自动套接字断开连接?

使用NSNetService连接到服务器但失败-自动套接字断开连接?
EN

Stack Overflow用户
提问于 2011-05-11 06:02:29
回答 1查看 3.2K关注 0票数 1

新的更简单的问题版本:

我正在尝试使用Objective-C客户端连接到Bonjour设备并与其通信,但在解析服务(服务器)时遇到了问题。最初我试图做一个更复杂的例子,但我发现基本的套接字连接,即使指定了端口/ip也不能工作。

我使用cocoaAsyncSocket库编写了尽可能多的基本代码:

代码语言:javascript
复制
AsyncSocket *xxx = [[[AsyncSocket alloc] initWithDelegate:self] autorelease];
NSError **err;
[xxx connectToHost: @"localhost" onPort: 5000 error: err];
NSLog(@"err=%@",err);

下面是我尝试连接的服务器(Python脚本):

代码语言:javascript
复制
# TCP server with bonjour broadcast!    
import select
import sys
import pybonjour
import socket
from time import sleep

#name    = sys.argv[1]
#regtype = sys.argv[2]
#port    = int(sys.argv[3])

# Bonjour service parameters
name = "TEST"
regtype = "_xxx._tcp."
port = 5000
# Tcp socket stuff
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("", port))
server_socket.listen(5)


def register_callback(sdRef, flags, errorCode, name, regtype, domain):
    if errorCode == pybonjour.kDNSServiceErr_NoError:
        print 'Registered service:'
        print '  name    =', name
        print '  regtype =', regtype
        print '  domain  =', domain

sdRef = pybonjour.DNSServiceRegister(name = name,
                                     regtype = regtype,
                                     port = port,
                                     callBack = register_callback)


# register bonjour service
print "Registering Bonjour service"
ready = select.select([sdRef], [], [])
print "ready=",ready
if sdRef in ready[0]:
    pybonjour.DNSServiceProcessResult(sdRef)

def configLoop():
    data = "Entering configuration mode"
    client_socket.send (data)
    data = "1) Network SSID: "
    client_socket.send (data)
    ssid = client_socket.recv(512)
    print "Network SSID:",ssid
    data = "2) Login: "
    client_socket.send (data)
    login = client_socket.recv(512)
    print "Login:",login
    data = "3) Password: "
    client_socket.send (data)
    passw = client_socket.recv(512)
    print "Password:",passw
    data = "Restarting server and attempting to connect to "+ssid
    client_socket.send (data)
    sleep(1)
    sys.exit(0)



print "TCPServer Waiting for client on port",port
try:
    while 1:

        client_socket, address = server_socket.accept()
        print "I got a connection from ", address

        data = "connection!"
        client_socket.send (data)

        while 1:
            data = client_socket.recv(512)
            if ( data == 'q' or data == 'Q'):
                client_socket.close()
                break;
            elif (data == 'C' or data == 'config'): # Enter configuration mode
                configLoop();
            else:
                print "RECIEVED:" , data

finally:
    sdRef.close()

服务器永远不会看到传入的连接。在客户端,error变量的值或其他值与我预期的完全不同。帮帮忙好吗?

旧(更复杂的版本,使用相同的服务器):

我的调试输出基本上显示服务已解决...然后我立即得到一个套接字断开连接。与此同时,我的服务器就在那里,还没有看到传入的连接。

当我获得初始连接并打印出服务的名称时,我已经遍历了调试器-然后它挂起,直到我按下continue,然后我得到一个套接字立即断开连接?

我对Objective-C和事件驱动编程非常陌生,所以也许我在处理一些错误的事情?非常感谢您的建议!

客户端(调试器)输出:

代码语言:javascript
复制
Running…
2011-05-10 14:10:26.822 Client[34709:a0f] TEST
2011-05-10 14:10:26.850 Client[34709:a0f] Socket disconnected
2011-05-10 14:10:29.724 Client[34709:a0f] Could not resolve: {
    NSNetServicesErrorCode = -72003;
    NSNetServicesErrorDomain = 10;
} 

服务器输出:

代码语言:javascript
复制
Registering Bonjour service
ready= ([<DNSServiceRef object at 0x100583290>], [], [])
Registered service:
  name    = TEST
  regtype = _xxx._tcp.
  domain  = local.
TCPServer Waiting for client on port 5000

客户端代码(ClientController.m,基本上取自http://www.macresearch.org/cocoa-scientists-part-xxix-message):

代码语言:javascript
复制
#import "ClientController.h"
#import "AsyncSocket.h"


@interface ClientController ()

@property (readwrite, retain) NSNetServiceBrowser *browser;
@property (readwrite, retain) NSMutableArray *services;
@property (readwrite, assign) BOOL isConnected;
@property (readwrite, retain) NSNetService *connectedService;
@property (readwrite, retain) MTMessageBroker *messageBroker;

@end


@implementation ClientController

@synthesize browser;
@synthesize services;
@synthesize isConnected;
@synthesize connectedService;
@synthesize socket;
@synthesize messageBroker;

-(void)awakeFromNib {
    services = [NSMutableArray new];
    self.browser = [[NSNetServiceBrowser new] autorelease];
    self.browser.delegate = self;
    self.isConnected = NO;
}

-(void)dealloc {
    self.connectedService = nil;
    self.browser = nil;
    self.socket = nil;
    self.messageBroker = nil;
    [services release];
    [super dealloc];
}

-(IBAction)search:(id)sender {
    [self.browser searchForServicesOfType:@"_xxx._tcp." inDomain:@""];
}

-(IBAction)connect:(id)sender {
    NSNetService *remoteService = servicesController.selectedObjects.lastObject;
    remoteService.delegate = self;
    [remoteService resolveWithTimeout:30];
    NSLog(@"%@",remoteService.name);
}

-(IBAction)send:(id)sender {
    NSData *data = [textView.string dataUsingEncoding:NSUTF8StringEncoding];
    NSLog(textView.string);
    // Use socket to send raw text data once connected
}

#pragma mark AsyncSocket Delegate Methods
-(void)onSocketDidDisconnect:(AsyncSocket *)sock {
    NSLog(@"Socket disconnected");
}

-(BOOL)onSocketWillConnect:(AsyncSocket *)sock {
    if ( messageBroker == nil ) {
        [sock retain];
        return YES;
    }
    return NO;
}

-(void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port {      
    //MTMessageBroker *newBroker = [[[MTMessageBroker alloc] initWithAsyncSocket:socket] autorelease];
    //[sock release];
    //newBroker.delegate = self;
    //self.messageBroker = newBroker;
    self.isConnected = YES;
}

#pragma mark Net Service Browser Delegate Methods
-(void)netServiceBrowser:(NSNetServiceBrowser *)aBrowser didFindService:(NSNetService *)aService moreComing:(BOOL)more {
    [servicesController addObject:aService];
}

-(void)netServiceBrowser:(NSNetServiceBrowser *)aBrowser didRemoveService:(NSNetService *)aService moreComing:(BOOL)more {
    [servicesController removeObject:aService];
    if ( aService == self.connectedService ) self.isConnected = NO;
}

-(void)netServiceDidResolveAddress:(NSNetService *)service {
    NSError *error;
    self.connectedService = service;
    self.socket = [[[AsyncSocket alloc] initWithDelegate:self] autorelease];
    [self.socket connectToAddress:service.addresses.lastObject error:&error];
}

-(void)netService:(NSNetService *)service didNotResolve:(NSDictionary *)errorDict {
    NSLog(@"Could not resolve: %@", errorDict);
}

@end
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-05-23 17:36:19

我也有同样的问题。问题似乎是连接已经存在:“尝试在连接时连接或接受连接。先断开连接”。不幸的是,我还没能解决这个问题。有什么想法吗?这可能是一个延迟或排序过程问题。

编辑:实际上,我把connectToAddress改成了ConnectToHost!:)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5957036

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档