iphone tcp连接 - 正在创建多个套接字

时间:2013-04-28 11:24:24

标签: iphone objective-c

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

我正在编写服务器部分的同事说,当我运行客户端时,我得到连接。当我点击连接按钮时,我打开一个连接并通过它发送初始消息但同时打开另一个套接字。 然后我继续从第一个连接接收所有消息,当我发送消息时,它通过第二个连接。 我的怀疑是 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

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:-1)

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

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