Java与Objective C之间的Socket连接

发布于 2024-11-10 04:04:24 字数 3389 浏览 0 评论 0原文

我正在尝试用 Java 编写一个服务器并使用 iPhone 应用程序(目标 C)与其进行通信。连接成功,我可以将数据写入服务器,但无法从服务器读回数据。我收到一条通知,有数据要读取,但它是空的。

Java 代码主要取自Oracle 示例

PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String inputLine;

out.println("Hello World");

while ((inputLine = in.readLine()) != null) {
    System.out.println(inputLine);
    System.out.flush();

    out.println("test");

    if (inputLine.equals("Bye")) {
        break;
    }
}

out.close();
in.close();
socket.close();

Objective C 客户端:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    [[UIApplication sharedApplication] setKeepAliveTimeout:600 handler:^(void) {
        NSLog(@"staying alive!");
        [[DABMultitaskingController sharedInstance] startTask];
    }];

    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;
    CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"10.0.1.189", 4444, &readStream, &writeStream);

    NSInputStream *inputStream = (NSInputStream *)readStream;
    NSOutputStream *outputStream = (NSOutputStream *)writeStream;
    [inputStream setDelegate:self];
    [outputStream setDelegate:self];
    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [inputStream open];
    [outputStream open];

    _dataToSend = [[NSData dataWithBytes:"This is a test" length:15] retain];

    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}

- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent
{
    switch (streamEvent) {
        case NSStreamEventHasBytesAvailable: {
            NSLog(@"can read: %@", theStream);

            uint8_t *buffer;
            NSUInteger length;
            [(NSInputStream *)theStream getBuffer:&buffer length:&length];
            NSData *data = [NSData dataWithBytes:buffer length:length];
            NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            NSLog(@"bytes: %@", data);
            NSLog(@"string: %@", string);

            break;
        }
        case NSStreamEventHasSpaceAvailable: {
            NSLog(@"can write: %@", theStream);

            if (_dataToSend != nil) {
                NSLog(@"write: %@", _dataToSend);
                [(NSOutputStream *)theStream write:[_dataToSend bytes] maxLength:[_dataToSend length]];
                [_dataToSend release];
                _dataToSend = nil;
            }

            break;
        }
        case NSStreamEventOpenCompleted: {
            NSLog(@"open complete: %@", theStream);

            break;
        }
        case NSStreamEventErrorOccurred: {
            NSLog(@"error occurred: %@", theStream);

            break;
        }
        case NSStreamEventEndEncountered: {
            NSLog(@"end encountered: %@", theStream);

            break;
        }
        default:
            break;
    }
}

I am trying to write a server in Java and communicate with it using an iPhone app (Objective C). The connection goes through, and I can write data to the server, but I can't read data back from the server. I get a notification that there is data to be read, but it's empty.

The Java code was taken mostly from an Oracle example.

PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String inputLine;

out.println("Hello World");

while ((inputLine = in.readLine()) != null) {
    System.out.println(inputLine);
    System.out.flush();

    out.println("test");

    if (inputLine.equals("Bye")) {
        break;
    }
}

out.close();
in.close();
socket.close();

And the Objective C client:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    [[UIApplication sharedApplication] setKeepAliveTimeout:600 handler:^(void) {
        NSLog(@"staying alive!");
        [[DABMultitaskingController sharedInstance] startTask];
    }];

    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;
    CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"10.0.1.189", 4444, &readStream, &writeStream);

    NSInputStream *inputStream = (NSInputStream *)readStream;
    NSOutputStream *outputStream = (NSOutputStream *)writeStream;
    [inputStream setDelegate:self];
    [outputStream setDelegate:self];
    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [inputStream open];
    [outputStream open];

    _dataToSend = [[NSData dataWithBytes:"This is a test" length:15] retain];

    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}

- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent
{
    switch (streamEvent) {
        case NSStreamEventHasBytesAvailable: {
            NSLog(@"can read: %@", theStream);

            uint8_t *buffer;
            NSUInteger length;
            [(NSInputStream *)theStream getBuffer:&buffer length:&length];
            NSData *data = [NSData dataWithBytes:buffer length:length];
            NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            NSLog(@"bytes: %@", data);
            NSLog(@"string: %@", string);

            break;
        }
        case NSStreamEventHasSpaceAvailable: {
            NSLog(@"can write: %@", theStream);

            if (_dataToSend != nil) {
                NSLog(@"write: %@", _dataToSend);
                [(NSOutputStream *)theStream write:[_dataToSend bytes] maxLength:[_dataToSend length]];
                [_dataToSend release];
                _dataToSend = nil;
            }

            break;
        }
        case NSStreamEventOpenCompleted: {
            NSLog(@"open complete: %@", theStream);

            break;
        }
        case NSStreamEventErrorOccurred: {
            NSLog(@"error occurred: %@", theStream);

            break;
        }
        case NSStreamEventEndEncountered: {
            NSLog(@"end encountered: %@", theStream);

            break;
        }
        default:
            break;
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

静赏你的温柔 2024-11-17 04:04:24

你永远不会将换行符 \n 发送到 java 端 BufferedReader 使用这些作为 readLine() 的分隔符;

_dataToSend = [[NSData dataWithBytes:"This is a test\n" length:16] retain];

you never send a linefeed \n to the java side BufferedReader uses these as delimiters for readLine();

_dataToSend = [[NSData dataWithBytes:"This is a test\n" length:16] retain];
恰似旧人归 2024-11-17 04:04:24

看起来我需要使用 read:maxLength: 来代替。现在工作正常。

Looks like I needed to use read:maxLength: instead. Works fine now.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文