Twisted服务器/iOS客户端发送和接收图像
我正试图将图像发送到twisted服务器并返回到我的iPhone。我的代码可以在模拟器上运行,但不能在iPhone上运行。我不知道为什么。我所做的只是将图像的数据发送到服务器,然后立即返回到我的iPhone。下面是我正在使用的相关代码Twisted服务器/iOS客户端发送和接收图像,ios,objective-c,networking,twisted,nsdata,Ios,Objective C,Networking,Twisted,Nsdata,我正试图将图像发送到twisted服务器并返回到我的iPhone。我的代码可以在模拟器上运行,但不能在iPhone上运行。我不知道为什么。我所做的只是将图像的数据发送到服务器,然后立即返回到我的iPhone。下面是我正在使用的相关代码 服务器端: 客户端: @接口登录屏幕:UIViewController{ } @属性(强,非原子)NSMutableData*outputData; @属性(强,非原子)IBUIImageView*测试图像; @实现登录屏幕:UIViewControlle
服务器端:
客户端:
@接口登录屏幕:UIViewController{
}
@属性(强,非原子)NSMutableData*outputData;
@属性(强,非原子)IBUIImageView*测试图像;
@实现登录屏幕:UIViewController
-(无效)网络通信{
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL,(CFStringRef)@“avis mbp”、80、&readStream和&writeStream);
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];
[输入流打开];
[输出流打开];
}
-(void)流:(NSStream*)流手柄通风口:(NSStreamEvent)流通风口{
开关(排气口){
已完成的案例:
打破
案例NSTRAVENTHASBYTES可用:
如果(theStream==inputStream){
uint8_t缓冲器[1024];
龙伦;
而([inputStream hasbytes可用]){
len=[inputStream读取:缓冲区maxLength:sizeof(缓冲区)];
如果(len>0){
NSData*输出=[[NSData alloc]initWithBytes:缓冲区长度:len];
if(nil!=输出){
[self.appDel.outputData appendBytes:缓冲区长度:len];
}
}
}
}
打破
发生错误的案例:
NSLog(@“无法连接到主机!”);
打破
案件被驳回:
NSLog(“事件结束”);
[溪流关闭];
[theStream removeFromRunLoop:[NSRunLoop currentRunLoop]forMode:NSDefaultRunLoopMode];
流=零;
打破
违约:
打破
}
}
-(iAction)runNetworkingTest:(id)发送方{
[自启动网络通信];
NSData*pictureData=UIImagePngResentation([UIImageName:@“shalin.jpg]”);
NSMutableData*mutedData=[[NSMutableData alloc]initWithData:pictureData];
[outputStream写入:[mutedData字节]最大长度:[mutedData长度]];
}
-(iAction)testPicture:(id)发送方{
UIImage*image=[UIImage imageWithData:self.outputData];
self.testImage.image=图像
}
我找到了解决问题的方法。这与写入服务器时可用的空间有关。iPhone一次只能写入特定数量的字节,因此我必须通过nsstreamventhasspaceavable案例来调节在委托中写入的数据量。下面是一段缺失的代码,它允许您将映像写入服务器,并通过TCP连接将其读回客户端到twisted服务器:
缺少要放入NSStream委托中的代码
运行网络测试的修改版本
显示图像的代码
注意:我一次写入1024字节。如果一次写入太多字节,它将不起作用。例如,我尝试了1024*8,但这对单个图像不起作用。但是,当我将缓冲区大小设置为1024时,我可以毫无问题地发送大约10个图像。我们需要的不仅仅是不工作。你得到了什么数据?有错误吗?很抱歉。我完全忘了指定错误。它显示了大约一半的图像,但其余部分是黑色的。我计算了每个实例中的字节数,发现当我在模拟器上运行它时,它传输244216字节,但在iPhone上它只传输131768字节。显然这就是问题所在,但我仍然不知道如何解决它。我想我解决了它。我没有处理流的写作方面。我需要解决NSStreamHasSpaceAvailable的问题。您能否将您的解决方案发布为子孙后代的答案?
from twisted.internet.protocol import Protocol, Factory
from twisted.internet import reactor
class IphoneChat(Protocol):
def connectionMade(self):
#self.transport.write("""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):
#print "data is ", data
self.transport.write(data);
def message(self, message):
self.transport.write(message + '\n')
factory = Factory()
factory.protocol = IphoneChat
factory.clients = []
reactor.listenTCP(80, factory)
print "Server Started"
reactor.run()
@interface LoginScreen : UIViewController <NSStreamDelegate> {
}
@property (strong, nonatomic) NSMutableData *outputData;
@property (strong, nonatomic) IBOutlet UIImageView *testImage;
@implementation LoginScreen : UIViewController
- (void)initNetworkCommunication {
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"avis-mbp", 80, &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)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {
switch (streamEvent) {
case NSStreamEventOpenCompleted:
break;
case NSStreamEventHasBytesAvailable:
if (theStream == inputStream) {
uint8_t buffer[1024];
long len;
while ([inputStream hasBytesAvailable]) {
len = [inputStream read:buffer maxLength:sizeof(buffer)];
if (len > 0) {
NSData *output = [[NSData alloc] initWithBytes:buffer length:len];
if (nil != output) {
[self.appDel.outputData appendBytes:buffer length:len];
}
}
}
}
break;
case NSStreamEventErrorOccurred:
NSLog(@"Can not connect to the host!");
break;
case NSStreamEventEndEncountered:
NSLog(@"Event Ended");
[theStream close];
[theStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
theStream = nil;
break;
default:
break;
}
}
-(IBAction)runNetworkingTest:(id)sender {
[self initNetworkCommunication];
NSData *pictureData = UIImagePNGRepresentation([UIImage imageNamed:@"shalin.jpg"]);
NSMutableData *mutedData = [[NSMutableData alloc] initWithData:pictureData];
[outputStream write:[mutedData bytes] maxLength:[mutedData length]];
}
-(IBAction)testPicture:(id)sender {
UIImage *image = [UIImage imageWithData:self.outputData];
self.testImage.image = image
}
case NSStreamEventHasSpaceAvailable:
{
if (self.appDel.willWrite && [self.appDel.inputData length] != 0) {
int bufferSize = 1024;
if ([self.appDel.inputData length] > bufferSize){
NSData *sendData = [self.appDel.inputData subdataWithRange:NSMakeRange(0, bufferSize)];
self.appDel.inputData = [[NSMutableData alloc] initWithData:[self.appDel.inputData subdataWithRange:NSMakeRange(bufferSize, [self.appDel.inputData length] - bufferSize)]];
[outputStream write:[sendData bytes] maxLength:[sendData length]];
} else {
[outputStream write:[self.appDel.inputData bytes] maxLength:[self.appDel.inputData length]];
self.appDel.inputData = [[NSMutableData alloc] init];
}
}
}
-(IBAction)runNetworkingTest:(id)sender {
[self initNetworkCommunication];
self.appDel.willWrite = YES;
NSData *pictureData = UIImagePNGRepresentation([UIImage imageNamed:@"shalin.jpg"]);
[self.appDel.inputData appendData:pictureData];
}
-(IBAction)showNetworkingArray:(id)sender {
UIImage *image = [UIImage imageWithData:self.appDel.outputData];
self.testImage.image = image;
}