我尝试根据此链接创建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
答案 0 :(得分:1)
您的日志表明您要么获得两条viewDidLoad
条消息,要么就是在两个不同的视图中获得一条消息。你根本没有提到改变观点,所以这似乎排除后者,留下前者。
尝试在viewDidLoad
中放置断点,并查看ViewController实例(self)是否两次都相同。如果它是相同的,你需要查看堆栈爬行并查看第二个调用的来源,因为hat通常表示在低内存事件后重新加载,这在现代设备上不应该发生。如果ViewController实例不同,那么您需要了解为什么要分配第二个ViewController。同样,堆栈跟踪可以帮助创建init方法并在其上设置断点。
答案 1 :(得分:-1)
不是您问题的真实答案,但为什么不使用CocoaAsyncSocket?
此框架提供了一个可以轻松使用的稳定Socket。它只会创建一个Socket并具有更多功能,并且可以使用像您这样的套接字修复的许多故障;)