我正在使用一个简单的python localhost服务器的聊天应用程序,使用NSStream通过网络套接字连接发送和接收数据。应用程序在iPhone应用程序中运行良好,但没有在mac应用程序中获得流。
我的Python服务器代码
from twisted.internet.protocol import Factory, Protocol
from twisted.internet import reactor
class MacChat(Protocol):
def connectionMade(self):
print "a client connected"
self.factory.clients.append(self)
print "clients are ", self.factory.clients
def connectionLost(self, reason):
self.factory.clients.remove(self)
def dataReceived(self, data):
a = data.split(':')
print a
if len(a) > 1:
command = a[0]
content = a[1]
msg = ""
if command == "iam":
self.name = content
msg = self.name + " has joined"
elif command == "msg":
msg = self.name + ": " + content
print msg
for c in self.factory.clients:
c.message(msg)
def message(self, message):
self.transport.write(message + '\n')
factory = Factory()
factory.clients = []
factory.protocol = MacChat
reactor.listenTCP(80, factory)
print "Mac Chat server started"
reactor.run()
Mac
ChatViewController.h
#import <Cocoa/Cocoa.h>
@interface ChatViewController : NSViewController
@property (strong,nonatomic) NSString *userName;
@end
ChatViewController.m
#import "ChatViewController.h"
@interface ChatViewController ()<NSTableViewDataSource,NSTableViewDelegate,NSStreamDelegate>
{
NSInputStream *inputStream;
NSOutputStream *outputStream;
NSMutableArray * messages;
}
@property (weak) IBOutlet NSButton *btnSend;
@property (weak) IBOutlet NSTextField *txtMessage;
@property (weak) IBOutlet NSTableView *tableview;
@end
@implementation ChatViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do view setup here.
}
-(void)setUserName:(NSString *)userName
{
[self initNetworkCommunication];
NSString *response = [NSString stringWithFormat:@"iam:%@",userName];
NSData *data = [[NSData alloc] initWithData:[response dataUsingEncoding:NSASCIIStringEncoding]];
[outputStream write:[data bytes] maxLength:[data length]];
messages = [[NSMutableArray alloc] init];
}
- (void)initNetworkCommunication {
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"localhost", 80, &readStream, &writeStream);
inputStream = (__bridge_transfer NSInputStream *)readStream;
outputStream = (__bridge NSOutputStream *)writeStream;
inputStream.delegate=self;
outputStream.delegate=self;
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inputStream open];
[outputStream open];
}
- (IBAction)btnAtnSend:(id)sender {
NSString *response = [NSString stringWithFormat:@"msg:%@", self.txtMessage.stringValue];
NSData *data = [[NSData alloc] initWithData:[response dataUsingEncoding:NSASCIIStringEncoding]];
[outputStream write:[data bytes] maxLength:[data length]];
self.txtMessage.stringValue = @"";
}
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
// Get a new ViewCell
NSTableCellView *cellView = [tableView makeViewWithIdentifier:tableColumn.identifier owner:self];
// Since this is a single-column table view, this would not be necessary.
// But it's a good practice to do it in order by remember it when a table is multicolumn.
if( [tableColumn.identifier isEqualToString:@"cell"] )
{
NSString *s = (NSString *) [messages objectAtIndex:row];
cellView.textField.stringValue = s;
}
return cellView;
}
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
return [messages count];
}
-(CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row
{
return 30;
}
#pragma mark NSStream Delegate
-(void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
{
switch (eventCode) {
case NSStreamEventOpenCompleted:
NSLog(@"Stream opened");
break;
case NSStreamEventHasBytesAvailable:
if (aStream == inputStream) {
uint8_t buffer[1024];
int len;
while ([inputStream hasBytesAvailable]) {
len = (int)[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:
{
[aStream close];
[aStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
break;
default:
NSLog(@"Unknown event");
}
}
- (void) messageReceived:(NSString *)message {
[messages addObject:message];
[self.tableview reloadData];
[self.tableview scrollRowToVisible:messages.count-1];
}
@end
答案 0 :(得分:0)
行。看起来这是基于raywenderlich.com的示例。
这个例子是有缺陷的,如#34;字形&#34;在评论部分:
本教程对数据如何从网络传送到应用程序做出了一些不正确的假设。
在构建此代码之前阅读字形的帖子。
对于您的特定问题,您对原始代码进行了大量更改。乍一看,我不清楚&#34; setUserName&#34;甚至被称为。
没有它,就不会发生任何其他事情。