简单的 Iphone 客户端连接到服务器
预先感谢那些查看我的问题的人。我是编程新手,也是 Objective-c 编程新手,我正在创建一个简单的客户端,它将连接到白天服务器并请求时间和日期,然后将其打印到屏幕上,我已经观看并阅读了很多教程现在,我想出了下面的代码,但我有一个问题,我无法读取用户输入的服务器地址的输入,我将使用该服务器地址来连接到服务器,这是我的代码,
我的控制器中的套接字代码。 m 文件
@interface NSStream (MyAdditions)
+ (void)getStreamsToHostNamed:(NSString *)hostName
port:(NSInteger)port
inputStream:(NSInputStream **)inputStreamPtr
outputStream:(NSOutputStream **)outputStreamPtr;
@end
@implementation NSStream (MyAdditions)
+ (void)getStreamsToHostNamed:(NSString *)hostName
port:(NSInteger)port
inputStream:(NSInputStream **)inputStreamPtr
outputStream:(NSOutputStream **)outputStreamPtr
{
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
assert(hostName != nil);
assert( (port > 0) && (port < 65536) );
assert( (inputStreamPtr != NULL) || (outputStreamPtr != NULL) );
readStream = NULL;
writeStream = NULL;
CFStreamCreatePairWithSocketToHost(
NULL,
(CFStringRef) hostName,
port,
((inputStreamPtr != nil) ? &readStream : NULL),
((outputStreamPtr != nil) ? &writeStream : NULL)
);
if (inputStreamPtr != NULL) {
*inputStreamPtr = [NSMakeCollectable(readStream) autorelease];
}
if (outputStreamPtr != NULL) {
*outputStreamPtr = [NSMakeCollectable(writeStream) autorelease];
}
}
@end
我的连接地址和端口
@implementation iPhoneClientViewController
-(void) connect {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *address = [defaults stringForKey:@"Address"]; // this is default one
if(!address) address = @"localhost";
NSLog(@"ADDRESS %@",address);
[NSStream getStreamsToHostNamed: address port:13 inputStream:&iStream outputStream:&oStream];
[iStream retain];
[oStream retain];
[iStream setDelegate:self];
[oStream setDelegate:self];
[iStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[oStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[iStream open];
[oStream open];
}
我的默认值是
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Title</key>
<string>iPhoneClient</string>
<key>StringsTable</key>
<string>Root</string>
<key>PreferenceSpecifiers</key>
<array>
<dict>
<key>Type</key>
<string>PSTextFieldSpecifier</string>
<key>Title</key>
<string>Server IP</string>
<key>Key</key>
<string>Address</string>
<key>DefaultValue</key>
<string>localhost</string>
<key>IsSecure</key>
<false/>
<key>KeyboardType</key>
<string>NumbersAndPunctuation</string>
<key>AutoCorrectType</key>
<string>No</string>
</dict>
</array>
</dict>
</plist>
我放了一个我的 ViewController.m 的文本字段
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
NSLog(@"Text Field contents %@",textField.text);
[textField resignFirstResponder];
return YES;
}
,当单击按钮时,我放置
- (IBAction)connectCommand:(id)sender {
// NSString *address = textField.text; // this is gives me error textField undeclared
// then i try this one
NSString *address = text.text;
if( iStream != nil) return;
[self connect];
}
然后运行程序,我输入地址,然后单击连接按钮,但它不起作用,它在输出屏幕上给我以下错误,
2011-10-03 17:49:14.903 iPhoneClient[360:b303] Text Field contents 64.90.182.55
2011-10-03 17:49:16.096 iPhoneClient[360:b303] ADDRESS localhost
2011-10-03 17:49:16.101 iPhoneClient[360:b303] >> : NSStreamEventErrorOccurred
2011-10-03 17:49:16.102 iPhoneClient[360:b303] << : NSStreamEventErrorOccurred
我的事件处理如下所示,
- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent
{
NSString *io;
if (theStream == iStream) io = @">>";
else io = @"<<";
NSString *event;
switch (streamEvent)
{
case NSStreamEventNone:
event = @"NSStreamEventNone - Can not connect to the host!";
break;
case NSStreamEventOpenCompleted:
event = @"NSStreamEventOpenCompleted";
break;
case NSStreamEventHasBytesAvailable:
event = @"NSStreamEventHasBytesAvailable";
if (theStream == iStream)
{
//read data
uint8_t buffer[1024];
int len;
while ([iStream hasBytesAvailable])
{
len = [iStream read:buffer maxLength:sizeof(buffer)];
if (len > 0)
{
NSString *input = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];
if (nil != input)
{
//do something with data
NSLog(@"%@",input);
}
}
}
}
break;
case NSStreamEventHasSpaceAvailable:
event = @"NSStreamEventHasSpaceAvailable";
break;
case NSStreamEventErrorOccurred:
event = @"NSStreamEventErrorOccurred";
break;
case NSStreamEventEndEncountered:
event = @"NSStreamEventEndEncountered";
[self disconnect];
break;
default:
event = @"** Unknown";
}
NSLog(@"%@ : %@", io, event);
}
任何人都可以帮助我用我的代码?或者建议我一个很好的教程,我可以看到代码示例并了解有关套接字的更多内容。
=================================================== =================================================== =
好吧,因为我是新人,所以不允许回复我自己的帖子,所以我会编辑它,
我想我会选择低级别,是的,处理 xml 有点复杂,所以我只是禁用了这些部分
//NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
//NSString *address = [defaults stringForKey:@"Address"];
//if(!address) address = @"localhost";]
,并将这段代码
NSString *address = [text text];
NSLog(@"ADDRESS %@",address);
现在放在我的我得到的输出屏幕 =
2011-10-03 18:58:57.758 iPhoneClient[424:b303] Text Field contents 64.90.182.55
2011-10-03 18:58:58.627 iPhoneClient[424:b303] ADDRESS 64.90.182.55
2011-10-03 18:58:58.685 iPhoneClient[424:b303] >> : NSStreamEventOpenCompleted
2011-10-03 18:58:58.686 iPhoneClient[424:b303] << : NSStreamEventOpenCompleted
2011-10-03 18:58:58.686 iPhoneClient[424:b303] << : NSStreamEventHasSpaceAvailable
2011-10-03 18:58:58.696 iPhoneClient[424:b303] >> : NSStreamEventHasBytesAvailable
2011-10-03 18:58:58.698 iPhoneClient[424:b303] >> : NSStreamEventEndEncountered
我认为它说它已连接但由于我对数据没有做任何事情,它会自行终止,因为我在上面放置了一个运行循环?
现在有人知道如何从服务器获取和打印日期和时间吗?
Thanks in advance those who view my question. i am new to programming and also new to Objective-c programming, i am creating a simple client that will connect to a daytime server and request what time and date it is then print it to the screen, i have watched and read lots of tutorials right now and came up with the below code but i have a problem i cant read input from user that will enter the server address and i will use that server address in order to connect to server here is my code
my socket codes in my controller.m file
@interface NSStream (MyAdditions)
+ (void)getStreamsToHostNamed:(NSString *)hostName
port:(NSInteger)port
inputStream:(NSInputStream **)inputStreamPtr
outputStream:(NSOutputStream **)outputStreamPtr;
@end
@implementation NSStream (MyAdditions)
+ (void)getStreamsToHostNamed:(NSString *)hostName
port:(NSInteger)port
inputStream:(NSInputStream **)inputStreamPtr
outputStream:(NSOutputStream **)outputStreamPtr
{
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
assert(hostName != nil);
assert( (port > 0) && (port < 65536) );
assert( (inputStreamPtr != NULL) || (outputStreamPtr != NULL) );
readStream = NULL;
writeStream = NULL;
CFStreamCreatePairWithSocketToHost(
NULL,
(CFStringRef) hostName,
port,
((inputStreamPtr != nil) ? &readStream : NULL),
((outputStreamPtr != nil) ? &writeStream : NULL)
);
if (inputStreamPtr != NULL) {
*inputStreamPtr = [NSMakeCollectable(readStream) autorelease];
}
if (outputStreamPtr != NULL) {
*outputStreamPtr = [NSMakeCollectable(writeStream) autorelease];
}
}
@end
My Connection address and port
@implementation iPhoneClientViewController
-(void) connect {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *address = [defaults stringForKey:@"Address"]; // this is default one
if(!address) address = @"localhost";
NSLog(@"ADDRESS %@",address);
[NSStream getStreamsToHostNamed: address port:13 inputStream:&iStream outputStream:&oStream];
[iStream retain];
[oStream retain];
[iStream setDelegate:self];
[oStream setDelegate:self];
[iStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[oStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[iStream open];
[oStream open];
}
my defaults are
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Title</key>
<string>iPhoneClient</string>
<key>StringsTable</key>
<string>Root</string>
<key>PreferenceSpecifiers</key>
<array>
<dict>
<key>Type</key>
<string>PSTextFieldSpecifier</string>
<key>Title</key>
<string>Server IP</string>
<key>Key</key>
<string>Address</string>
<key>DefaultValue</key>
<string>localhost</string>
<key>IsSecure</key>
<false/>
<key>KeyboardType</key>
<string>NumbersAndPunctuation</string>
<key>AutoCorrectType</key>
<string>No</string>
</dict>
</array>
</dict>
</plist>
i put a text field to my ViewController.m
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
NSLog(@"Text Field contents %@",textField.text);
[textField resignFirstResponder];
return YES;
}
and when button clicked i put
- (IBAction)connectCommand:(id)sender {
// NSString *address = textField.text; // this is gives me error textField undeclared
// then i try this one
NSString *address = text.text;
if( iStream != nil) return;
[self connect];
}
then i run program i enter the address then i click to connect button but it doesnt work it gives me following errors on output screen
2011-10-03 17:49:14.903 iPhoneClient[360:b303] Text Field contents 64.90.182.55
2011-10-03 17:49:16.096 iPhoneClient[360:b303] ADDRESS localhost
2011-10-03 17:49:16.101 iPhoneClient[360:b303] >> : NSStreamEventErrorOccurred
2011-10-03 17:49:16.102 iPhoneClient[360:b303] << : NSStreamEventErrorOccurred
my event handling is like following
- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent
{
NSString *io;
if (theStream == iStream) io = @">>";
else io = @"<<";
NSString *event;
switch (streamEvent)
{
case NSStreamEventNone:
event = @"NSStreamEventNone - Can not connect to the host!";
break;
case NSStreamEventOpenCompleted:
event = @"NSStreamEventOpenCompleted";
break;
case NSStreamEventHasBytesAvailable:
event = @"NSStreamEventHasBytesAvailable";
if (theStream == iStream)
{
//read data
uint8_t buffer[1024];
int len;
while ([iStream hasBytesAvailable])
{
len = [iStream read:buffer maxLength:sizeof(buffer)];
if (len > 0)
{
NSString *input = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];
if (nil != input)
{
//do something with data
NSLog(@"%@",input);
}
}
}
}
break;
case NSStreamEventHasSpaceAvailable:
event = @"NSStreamEventHasSpaceAvailable";
break;
case NSStreamEventErrorOccurred:
event = @"NSStreamEventErrorOccurred";
break;
case NSStreamEventEndEncountered:
event = @"NSStreamEventEndEncountered";
[self disconnect];
break;
default:
event = @"** Unknown";
}
NSLog(@"%@ : %@", io, event);
}
can any one help me with my code? or suggests me a good me a good tutorial that i can see examples of codes and learn more stuff about sockets.
=====================================================================================================
alright since i am new it is not allowed to reply my own post so i will edit it
i think i will go with low level, yes dealing with xml is little bit complicating so i just disabled the parts
//NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
//NSString *address = [defaults stringForKey:@"Address"];
//if(!address) address = @"localhost";]
and put this code
NSString *address = [text text];
NSLog(@"ADDRESS %@",address);
now in my output screen i get following =
2011-10-03 18:58:57.758 iPhoneClient[424:b303] Text Field contents 64.90.182.55
2011-10-03 18:58:58.627 iPhoneClient[424:b303] ADDRESS 64.90.182.55
2011-10-03 18:58:58.685 iPhoneClient[424:b303] >> : NSStreamEventOpenCompleted
2011-10-03 18:58:58.686 iPhoneClient[424:b303] << : NSStreamEventOpenCompleted
2011-10-03 18:58:58.686 iPhoneClient[424:b303] << : NSStreamEventHasSpaceAvailable
2011-10-03 18:58:58.696 iPhoneClient[424:b303] >> : NSStreamEventHasBytesAvailable
2011-10-03 18:58:58.698 iPhoneClient[424:b303] >> : NSStreamEventEndEncountered
i thinks it says it connected but since i do nothing with data it is terminating itself because i put a run loop above?
now anyone know how can i fetch and print date and time from server?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
高级别反馈:
我建议使用字节流与服务器进行通信的级别太低。
相反,请考虑使用 JSON 或 XML 作为更易于管理的格式。通过将其与 RESTful API 相结合,您可以使用来自 iOS 的 HTTP 请求,并以更高效、更便携和更易于管理的方式与您的服务器进行通信。
希望有帮助。
High Level Feedback:
I would suggest that communicating with your server using byte streams is too low a level.
Instead, consider using JSON or XML as a more manageable format. By combining this with a RESTful API you can use HTTP Requests from iOS, and communicate with your server in a more productive, portable, and manageable way.
Hope that helps.
在方法中:
当用户按键盘上的 Tab 键返回键时:
in methods:
when user tab return key on keyboard: