iPhone TCP/IP套接字服务器/客户端程序

iPhone TCP/IP套接字服务器/客户端程序,iphone,sockets,connection,communication,Iphone,Sockets,Connection,Communication,我在这个网站上读了很多关于这个主题的问题,但是他们没有安静地回答我的问题。如果你不能了解我的目标或背景,请跳到问题上来 我的目标 就是要构建一个可以在Mac OS X 10.4+及更高版本上运行的服务器,并将其移植到Windows XP/Vista(目前还不知道如何做到这一点,但这是以后的问题) 然后,让iPhone成为能够查看运行服务器的计算机名称的客户端(通过WiFi)。然后,iPhone用户可以选择要连接到该计算机上服务器的计算机名 之后,他们可以互相发送简单的短信。例如,iPhone发送

我在这个网站上读了很多关于这个主题的问题,但是他们没有安静地回答我的问题。如果你不能了解我的目标或背景,请跳到问题上来

我的目标

就是要构建一个可以在Mac OS X 10.4+及更高版本上运行的服务器,并将其移植到Windows XP/Vista(目前还不知道如何做到这一点,但这是以后的问题)

然后,让iPhone成为能够查看运行服务器的计算机名称的客户端(通过WiFi)。然后,iPhone用户可以选择要连接到该计算机上服务器的计算机名

之后,他们可以互相发送简单的短信。例如,iPhone发送“敲门敲门”,服务器响应“谁在那里?”。或者一个简单的客户端:“Ping”,服务器响应“Pong”就可以了

背景

我以前使用过套接字,但只有在VisualBasic6中使用WINSOCKET.dll时,创建TCP/IP服务器才非常容易

server.host = localhost;
server.port = 12203;
server.listen(); 
对于客户端,我只需要执行以下操作即可连接

client.connect(localhost, 12203);
有一些回调可用,如connect、close、dataArrival等,我可以用它们来做任何我想做的事情

也许iPhone有专门为它编写的库,但是自己创建这个简单的应用程序有那么难吗?在做了一些研究之后,我了解到我必须研究CFNetwork、CFHost、CFSocket和CFStream领域

问题

有没有人可以指导我阅读教程或在iPhone上有两个按钮的地方发布代码。[启动服务器]和[连接到服务器],其中第一个将在某个端口上启动TCP/IP服务器,第二个连接到该端口

建立连接后,服务器接收到简单的“Ping”消息后,向服务器发送该消息的代码也可能会向客户端发送一条“Pong”消息


那真的很有帮助。但也许我在这里要求更多。

我希望您希望您的服务器已经启动,然后您只需要一个“连接到服务器”按钮,然后是“Ping”。否则,您的服务器盒上需要一个单独的进程来响应“启动服务器”消息并启动服务器。

我建议如下:

网站上还有一个基本的示例项目可以帮助您开始。我在使用该框架时取得了很好的成功。

创建聊天示例应用程序非常有效,而且非常简单(像我一样,任何iphone noob都可以让它工作,即使在模拟器模式下,它连接到外部套接字服务器)

我把它改装成了我的socket服务器,它工作起来很有魅力。这是测试代码,所以没有真正的问题。它只发送一条消息(您的登录id)并收到回复,该回复显示在控制台中

//
//  ViewController.m
//  zdelSocketTest01a
//
//

#import "ViewController.h"



@implementation ViewController
@synthesize inputNameField;
@synthesize joinView;

- (void)initNetworkCommunication {

    uint portNo = 5555;
    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;
    CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"227.3.4.56", portNo, &readStream, &writeStream);
    inputStream = (__bridge NSInputStream *)readStream;
    outputStream = (__bridge NSOutputStream *)writeStream;

    [inputStream setDelegate:self];
    [outputStream setDelegate:self];

    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [inputStream open];
    [outputStream open];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

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

- (void)viewDidUnload
{
    [self setInputNameField:nil];
    [self setJoinView:nil];
    [self setJoinView:nil];
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

- (IBAction)joinChat:(id)sender {

    NSString *response  = [NSString stringWithFormat:@"logon,%@", inputNameField.text];
    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);
 }
 */

- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {
    typedef enum {
        NSStreamEventNone = 0,
        NSStreamEventOpenCompleted = 1 << 0,
        NSStreamEventHasBytesAvailable = 1 << 1,
        NSStreamEventHasSpaceAvailable = 1 << 2,
        NSStreamEventErrorOccurred = 1 << 3,
        NSStreamEventEndEncountered = 1 << 4
    };
    uint8_t buffer[1024];
    int len;

    switch (streamEvent) {

        case NSStreamEventOpenCompleted:
            NSLog(@"Stream opened now");
            break;
        case NSStreamEventHasBytesAvailable:
            NSLog(@"has bytes");
            if (theStream == inputStream) {
                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);
                        }
                    }
                }
            } else {
                NSLog(@"it is NOT theStream == inputStream");
            }
            break;
        case NSStreamEventHasSpaceAvailable:
            NSLog(@"Stream has space available now");
            break;


        case NSStreamEventErrorOccurred:
            NSLog(@"Can not connect to the host!");
            break;


        case NSStreamEventEndEncountered:

            [theStream close];
            [theStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

            break;

        default:
            NSLog(@"Unknown event %i", streamEvent);
    }

}
/*
 - (void) messageReceived:(NSString *)message {

 [messages addObject:message];
 [self.tView reloadData];

 }
 */

@end
//
//ViewController.m
//zdelSocketTest01a
//
//
#导入“ViewController.h”
@实现视图控制器
@综合输入名称字段;
@综合观点;
-(无效)网络通信{
uint端口号=5555;
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL,(CFStringRef)@“227.3.4.56”、端口号、读取流和写入流);
inputStream=(uu桥NSInputStream*)readStream;
outputStream=(uu桥NSOutputStream*)writeStream;
[inputStream setDelegate:self];
[outputStream setDelegate:self];
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]forMode:NSDefaultRunLoopMode];
[outputStream ScheduleRunLoop:[NSRunLoop currentRunLoop]forMode:NSDefaultRunLoopMode];
[输入流打开];
[输出流打开];
}
-(无效)未收到记忆警告
{
[超级记忆警告];
//释放所有未使用的缓存数据、图像等。
}
#pragma标记-视图生命周期
-(无效)viewDidLoad
{
[超级视图下载];
//加载视图后,通常从nib执行任何其他设置。
[自启动网络通信];
messages=[[NSMutableArray alloc]init];
}
-(无效)视图卸载
{
[self-setInputNameField:nil];
[自设置连接视图:无];
[自设置连接视图:无];
[超级视频下载];
//释放主视图的所有保留子视图。
//例如,self.myOutlet=nil;
}
-(无效)视图将显示:(BOOL)动画
{
[超级视图将显示:动画];
}
-(无效)视图显示:(BOOL)动画
{
[超级视图显示:动画];
}
-(无效)视图将消失:(BOOL)已设置动画
{
[超级视图将消失:动画];
}
-(无效)视图消失:(BOOL)已设置动画
{
[超级视窗消失:动画];
}
-(布尔)应自动旋转指针面定向:(UIInterfaceOrientation)interfaceOrientation
{
//对于支持的方向返回YES
返回(interfaceOrientation!=UIInterfaceOrientation肖像向上向下);
}
-(iAction)joinChat:(id)发件人{
NSString*响应=[NSString stringWithFormat:@“登录,%@”,inputNameField.text];
NSData*data=[[NSData alloc]initWithData:[response dataUsingEncoding:NSASCIIStringEncoding]];
[outputStream写入:[数据字节]最大长度:[数据长度]];
}
/*
-(void)流:(NSStream*)流手柄通风口:(NSStreamEvent)流通风口{
NSLog(@“流事件%i”,流事件);
}
*/
-(void)流:(NSStream*)流手柄通风口:(NSStreamEvent)流通风口{
类型定义枚举{
NST=0,

NSSTREATEVENTOPENCOMPLETED=1哦,这就是它的工作原理?要能够将服务器检测为客户端,您需要向特定的本地ip范围发送消息(例如192.168.1.1->255)每个回复你在TableView中的邮件的服务器。好的,我会明白的。还有什么方法可以帮我回答我问题的第二部分吗?如何在两者之间获得ping?如果你至少对每个答案都进行评论,你不会问太多。投票给解决方案也会很好。@FahimParkar这是个问题工作版本的ce代码。如果您发现
#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <NSStreamDelegate>
@property (weak, nonatomic) IBOutlet UITextField *inputNameField;
@property (weak, nonatomic) IBOutlet UIView *joinView;
- (IBAction)joinChat:(id)sender;


@end
NSInputStream *inputStream;
NSOutputStream *outputStream;
NSMutableArray * messages;