我正在制作一个感应iBeacons的应用程序。当你进入iBeacon的直接范围时,应用程序将信标的主要和次要编号发送到服务器,服务器发送回存储在MySQL数据库中的图像,根据主要和次要编号发送回不同的图像
应用程序通过NSStream将主要和次要编号发送到Python(扭曲套接字)脚本,该脚本使用这些编号从数据库中获取图像并将其发送回应用程序。
当我使用它从数据库中获取简单的文本消息时,这个设置很有用,但是当我尝试在应用程序内接收和显示图像时遇到了问题。
首先我将发布流的代码:handleEvent,它接收来自输入流的数据。
的略微修改// input stream event that recieves the data from the server
//
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
{
switch (eventCode)
{
case NSStreamEventOpenCompleted:
NSLog(@"stream opened");
break;
case NSStreamEventHasBytesAvailable: // event for recieving data
NSLog(@"Recieved Data");
if (aStream == _inputStream)
{
uint8_t buffer[500000];
int len;
// loop gets bytes from input stream
//
while ([_inputStream hasBytesAvailable])
{
len = [_inputStream read:buffer maxLength:sizeof(buffer)];
if (len > 0)
{
NSString *str = @"data:image/jpg;base64,";
NSString *img = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];
str = [str stringByAppendingString:img];
NSData *ImgOut = [NSData dataWithContentsOfURL:[NSURL URLWithString:str]];
if (nil != ImgOut)
{
self.ImageView.image = [UIImage imageWithData:ImgOut];
NSLog(@"show image");
}
}
}
}
break;
case NSStreamEventErrorOccurred:
NSLog(@"can not connect to host");
[self initNetworkComms];
break;
case NSStreamEventEndEncountered:
NSLog(@"Connection Lost");
[_outputStream close];
[_inputStream close];
[self initNetworkComms];
break;
default:
NSLog(@"unkown event");
break;
}
}
为了好的衡量标准,我将发布Python脚本的代码
from twisted.internet.protocol import Protocol, Factory
from twisted.internet import reactor
import mysql.connector
db = mysql.connector.connect(user='NotImportant', password='WouldntYouLikeToKnow', host='localhost', database='retailbeacons')
cursor = db.cursor()
class MessageServer(Protocol):
def connectionMade(self):
self.factory.clients.append(self)
print "clients are ", self.factory.clients
def connectionLost(self, reason):
self.factory.clients.remove(self)
print "client has disconnected"
def dataReceived(self, data):
a = data.split(':')
if len(a) > 1:
Major = a[0]
Minor = a[1]
msg = ""
print "Received query " + Major + ":" + Minor
sql = "SELECT Picture FROM beaconinfo WHERE major=" + Major + " AND minor=" + Minor + ";"
cursor.execute(sql)
for row in cursor.fetchall():
mess = row[0]
msg = mess.encode('utf=8')
self.message(msg)
def message(self, message):
self.transport.write(message + '\n')
factory = Factory()
factory.protocol = MessageServer
factory.clients = []
reactor.listenTCP(8080, factory)
print "Python message test server started"
reactor.run()
此代码发生的情况是,当应用程序查询服务器时,服务器发送回图像数据(以base64格式),应用程序接收此数据并触发switch语句的EventHasBytesAvailable情况。但是只显示了图像的一小部分,我得到一个错误日志:
<Error>: ImageIO: JPEG Corrupt JPEG data: premature end of data segment
这让我相信并非所有数据都来自流。你会在代码中看到我有一个NSLog说“收到的数据”#39;每次调用EventHasBytesAvailable案例并且&#39;显示图像&#39;当使用图像数据设置UIImageView时。
我发现奇怪的事情,我觉得这个问题的根源是当EventHasBytesAvailable被称为“收到的数据”时。记录消息,然后显示图像&#39;记录消息,然后再次记录“收到的数据”。记录消息,然后记录上面列出的错误。
所以看起来有一小部分数据通过流进入,循环收集这些字节并将它们粘贴在UIImageView中,然后更多字节通过流进入并尝试将它们放入UIImageView中但是数据段的过早结束了#9;发生错误。
我很困惑为什么会这样。不应该通过一次调用EventHasBytesAvailable案例来通过流发送图像的整个数据吗?可能我在代码中看了缓冲区?我的缓冲区可以拍摄60kb的图像吗?这是我能想到的唯一可能与应用程序代码相关的东西,然后我能想到的可能是Python脚本是以两个块而不是一个块发送数据。
感谢您的时间。我是一个实习生,用这个打了一个墙!任何帮助将不胜感激!
答案 0 :(得分:0)
解决了这个问题。因此,该流正在多次调用“HasBytes”中发送数据。案件。所以我创建了一个字符串,当&#39; HasBytes&#39;时,它会附加每个数据块。被叫。我还使用了另一种方法将图像数据字符串转换为NSData对象。
NSString *ImgStr = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];
// string property for appending
//
_str = [_str stringByAppendingString:ImgStr];
NSData *ImgData = [[NSData alloc] initWithBase64EncodedString:_str options:1];
if (nil != ImgData)
{
self.ImageView.image = [UIImage imageWithData:ImgData];
}
非常感谢!