0

我尝试按照此链接 http://www.raywenderlich.com/3932/how-to-create-a-socket-based-iphone-app-and-server创建 tcp 连接

我正在编写服务器部分的同事说,当我运行客户端时,我会建立连接。当我单击加入按钮时,我打开一个连接并通过该连接发送初始消息,但同时打开另一个套接字。然后,我连续接收来自第一个连接的所有消息,当我发送消息时,它通过第二个连接。我的疑问是 1) 为什么要在这里创建 2 个连接/套接字?2)为什么我不能通过同一个连接读写?3)这是否意味着如果有 300 个客户端用户,将打开 600 个连接?

我是iphone编程的初学者。所以如果我不清楚,请原谅。

#import "ViewController.h"
@implementation ViewController
@synthesize txtUsername,txtPassword,webData,responseString,sessionId;
@synthesize inputStream, outputStream,messages;

- (void)viewDidLoad
{
    [super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
    NSLog(@"Entered main");
    [self initNetworkCommunication];
    messages = [[NSMutableArray alloc] init];
}


- (IBAction)usernExit:(id)sender {
    [txtUsername resignFirstResponder];
}

- (IBAction)pwdExit:(id)sender {
    [txtPassword resignFirstResponder];

}

- (IBAction)btnLogin:(id)sender {

    NSLog(@"Clicked button1");

    NSString *response  = [NSString stringWithFormat:@"PMS|Login|user1|sssss"];

NSData *data = [[NSData alloc] initWithData:[response dataUsingEncoding:NSASCIIStringEncoding]];
[outputStream write:[data bytes] maxLength:[data length]];

}

- (void) initNetworkCommunication {
    NSLog(@"initNetworkCommunication called");

CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"xxx.xxx.xx.xx", xxxx, &readStream, &writeStream);
inputStream = (NSInputStream *)readStream;
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];
}
- (IBAction)sendMessage:(id)sender {
    NSLog(@"sendMessage called");

    NSString *response  = [NSString stringWithFormat:@"PMS|Msg"];
NSData *data = [[NSData alloc] initWithData:[response dataUsingEncoding:NSASCIIStringEncoding]];
[outputStream write:[data bytes] maxLength:[data length]];




}

- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {

NSLog(@"stream event %i", streamEvent);
switch (streamEvent) {
case NSStreamEventOpenCompleted:
NSLog(@"Stream opened");
break;
case NSStreamEventHasBytesAvailable:

if (theStream == inputStream) {
uint8_t buffer[1024];
int len;
while ([inputStream hasBytesAvailable]) {
len = [inputStream read:buffer maxLength:sizeof(buffer)];
if (len > 0) {
NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];

if (nil != output) {

NSLog(@"server said: %@", output);
[self messageReceived:output];
}
}
}
}
break;

case NSStreamEventErrorOccurred:
NSLog(@"Can not connect to the host!");
break;
case NSStreamEventEndEncountered:
            NSLog(@"NSStreamEventEndEncountered:method is called");
            [theStream close];
            NSLog(@"theStream is closed");

            [theStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
            NSLog(@"theStream is removed from runloop");

            [theStream release];
            NSLog(@"theStream is released");

            theStream = nil;
break;
default:
NSLog(@"Unknown event");
}

}//End of stream
- (void) messageReceived:(NSString *)message {
    NSLog(@"Entered MessageRecieved");
[messages addObject:message];

}


- (void)dealloc {

[messages release];
    [super dealloc];
}


@end

.h 文件

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <NSStreamDelegate>

@property (retain, nonatomic) IBOutlet UITextField *txtUsername;
@property (retain, nonatomic) IBOutlet UITextField *txtPassword;
@property (retain, nonatomic) NSMutableData *webData;
@property (retain, nonatomic) NSString *responseString;
@property (retain, nonatomic) NSString *sessionId;


@property (retain, nonatomic) NSInputStream *inputStream;
@property (retain, nonatomic) NSOutputStream *outputStream;
@property (nonatomic, retain) NSMutableArray *messages;

- (IBAction)usernExit:(id)sender;
- (IBAction)pwdExit:(id)sender;
- (IBAction)btnLogin:(id)sender;
- (void)initNetworkCommunication;
- (IBAction)sendMessage:(id)sender;
- (IBAction)sendMsgAgain:(id)sender;

@end
the logs
------------------
When i run the program
-----------------------------
2013-04-29 03:57:57.826 TestConnection[13670:11303] Entered main
2013-04-29 03:57:57.827 TestConnection[13670:11303] initNetworkCommunication called
2013-04-29 03:57:57.846 TestConnection[13670:11303] stream event 1
2013-04-29 03:57:57.847 TestConnection[13670:11303] Stream opened
2013-04-29 03:57:57.847 TestConnection[13670:11303] stream event 1
2013-04-29 03:57:57.847 TestConnection[13670:11303] Stream opened
2013-04-29 03:57:57.847 TestConnection[13670:11303] stream event 4
2013-04-29 03:57:57.847 TestConnection[13670:11303] Unknown event

When i click the first button
------------------------------------
2013-04-29 03:58:17.994 TestConnection[13670:11303] Clicked button1
2013-04-29 03:58:17.997 TestConnection[13670:11303] Entered main
2013-04-29 03:58:17.998 TestConnection[13670:11303] initNetworkCommunication called
2013-04-29 03:58:17.999 TestConnection[13670:11303] stream event 4
2013-04-29 03:58:17.999 TestConnection[13670:11303] Unknown event
2013-04-29 03:58:18.005 TestConnection[13670:11303] stream event 1
2013-04-29 03:58:18.005 TestConnection[13670:11303] Stream opened
2013-04-29 03:58:18.005 TestConnection[13670:11303] stream event 1
2013-04-29 03:58:18.005 TestConnection[13670:11303] Stream opened
2013-04-29 03:58:18.005 TestConnection[13670:11303] stream event 4
2013-04-29 03:58:18.006 TestConnection[13670:11303] Unknown event
2013-04-29 03:58:18.122 TestConnection[13670:11303] stream event 2
2013-04-29 03:58:18.123 TestConnection[13670:11303] New String JSESSIONID=56be3c2f6bbb30a6a8d0728dc710
2013-04-29 03:58:18.123 TestConnection[13670:11303] server said: JSESSIONID=56be3c2f6bbb30a6a8d0728dc710
WebLoginReplyType_t.Accepted
2013-04-29 03:58:18.124 TestConnection[13670:11303] Entered MessageRecieved
4

2 回答 2

1

您的日志表明您要么收到两条viewDidLoad消息,要么在两个不同的视图中各收到一条。你根本没有提到改变观点,所以这似乎排除了后者,留下了前者。

尝试在其中放置一个断点viewDidLoad并查看两次 ViewController 实例(self)是否相同。如果相同,则需要查看堆栈爬网并查看第二次调用来自何处,因为 hat 通常表示在内存不足事件后重新加载,这在现代设备上不应该发生。如果 ViewController 实例不同,那么您需要查看为什么要分配第二个 ViewController。同样,堆栈跟踪可以帮助创建一个 init 方法并在其上设置一个断点。

于 2013-04-29T12:21:15.777 回答
-1

不是您问题的真正答案,但为什么不使用CocoaAsyncSocket呢?

该框架提供了一个稳定的 Socket,您可以轻松使用。它将只创建一个 Socket 并具有更多功能,并且可以使用像您这样的套接字进行的许多故障已经修复;)

于 2013-04-29T11:20:15.027 回答