socket简单的通信demo
首先,我要先了解下即时通信主要用到了哪些技术?
1.语音聊天模块
从技术上讲主要就是录音:把录音文件发到服务器,再从服务器传到另外一个设备进行播放,这个过程是非常简单的,但是考虑一个问题就是要适合网络传输,因为网络是特别脆弱的,不管是发的时候还是收的时候它会占到我们手机的流量,这个流量是大家比较关心的,因为这个网络确实太贵了,为了便于网络传输我们进行一个压缩和解压的过程,知道这个过程之后,我们可以进入我们iOS平台要讲的东西。第一个是语音录制、语音编解码、语音播放,还有Audaio Session还有语音实践。
在语音录制里面我们会讲哪几个,我们比较想了解就是IOS里面录制哪些语音格式,还有我们的API怎么去使用,还有录制的音量怎么样,录制的时候波浪会随着我们声音大小变换,这个是IOS也支持的。
我们看看iOS支持默认语音录制格式,他支持的格式不是很多,很多我们想要可能没有,但是我们可以给大家介绍基本的格式它是支持的AAC压缩比较高,效果比较好。还有ALAC,还有ILBC,这个用于网络传输的一个语音格式。IMA4这是一个压缩效率很高,但是各方面因为效率高了,可能别的算法、复杂度可能降一点,要求效率比较高考虑这种格式,还有LINEAR PCM,这个是无压缩的,还有U—LAW和ALAW。
刚开始,我先分析了一个简单的基于UDP的socket的在局域网内聊天的即时通讯项目,主要实现发送信息的功能
首先导入第三方库:AsyncUdpSocket.h,AsyncUdpSocket.m;IPAddress.h,IPAddress.c;
然后你了解一下UDP的socket通信的工作流程,见UDP Socket通信。
现在开始编写代码实现:
1.在通信开始前,先要获取自己设备的id,这是在三方库中已经封装好了的,可以直接使用:
NSString *ip_iphone = [selfdeviceIPAdress];
self.myIP = ip_iphone;
//得到本机IP
-(NSString *) deviceIPAdress
{
InitAddresses();
GetIPAddresses();
GetHWAddresses();
return [NSStringstringWithFormat:@"%s",ip_names[1]];
}
-(void)openUDPServer
{
//初始化udp
self.udpSocket = [[AsyncUdpSocketalloc]initWithDelegate:self];
//绑定端口
[self.udpSocketbindToPort:8088error:nil];
//发送广播设置
[self.udpSocketenableBroadcast:YESerror:nil];
//加入广播组,能接收群里其他客户端的消息
[self.udpSocketjoinMulticastGroup:@"224.0.0.2"error:nil];
//启动接收线程
[self.udpSocketreceiveWithTimeout:-1tag:0];
}
若要使用多点广播时,则需要让一个数据报标有一组目标主机地址,当数据报发出后,整个组的所有主机都能收到该数据报。IP多点广播(或多点发送)实现了将单一信息发送到多个接收者的广播,其思想是设置一组特殊网络地址作为多点广播地址,每一个多点广播地址都被看做一个组,当客户端需要发送、接收广播信息时,加入到该组即可。
IP协议为多点广播提供了一批特殊的IP地址,下面列举几个常见的:
224.0.0.1 子网上的所有系统
224.0.0.2 子网上的所有路由器
224.0.0.12 dhcp服务器
224.0.1.1 ntp
224.0.1.24 wins服务器
3.UDP代理:socket开始接收数据
-(BOOL)onUdpSocket:(AsyncUdpSocket *)sock didReceiveData:(NSData *)data withTag:(long)tag fromHost:(NSString *)host port:(UInt16)port
{
[self.udpSocketreceiveWithTimeout:-1tag:0];
NSLog(@"host -- >%@",host);
//收到自己发的广播消息不显示
NSMutableString *tempIP = [NSMutableStringstringWithFormat:@"::ffff:%@",self.myIP];
if ([host isEqualToString:self.myIP] || [hostisEqualToString:tempIP])
{
return NO;
}
//接收到数据,在UITableView中显示出来
NSString *info = [[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding];
NSLog(@"%@",info);
[self.chatArrayaddObject:[NSDictionarydictionaryWithObjectsAndKeys:info,@"text",@"other",@"speaker", nil]];
[self.tableViewreloadData];
[self.tableViewscrollToRowAtIndexPath:[NSIndexPathindexPathForRow:[self.chatArraycount]-1inSection:0]
atScrollPosition:UITableViewScrollPositionBottom
animated:YES];
//已经处理完毕
return YES;
}
UIImageView *bubbleImageView = [[UIImageViewalloc]initWithImage:[bubblestretchableImageWithLeftCapWidth:21topCapHeight:14]];
根据设置的宽度和高度,将接下来的一个像素进行左右扩展和上下拉伸。
注意:可拉伸的范围都是距离leftCapWidth后的1竖排像素,和距离topCapHeight后的1横排像素。
参数的意义是,如果参数指定10,5。那么,图片左边10个像素,上边5个像素。不会被拉伸,x坐标为11和一个像素会被横向复制,y坐标为6的一个像素会被纵向复制。
注意:只是对一个像素进行复制到一定宽度。而图像后面的剩余像素也不会被拉伸。CGSize size = [text sizeWithFont:font constrainedToSize:CGSizeMake(150.0f, 1000.0f)lineBreakMode:UILineBreakModeCharacterWrap];
延伸:获取字符串不折行显示时所需的长度:CGSize titleSize = [aString sizeWithFont:font constrainedToSize:CGSizeMake(MAXFLOAT, 30)];
获取字符串在指定长度内,所需的宽度:CGSize titleSize = [aString sizeWithFont:font constrainedToSize:CGSizeMake(60, MAXFLOAT)];
判断字符串是否需要折行的代码:
CGSize sz = [label.text sizeWithFont:label.font
constrainedToSize:CGSizeMake(MAXFLOAT, 40)];
CGSize linesSz = [label.text sizeWithFont:label.font
constrainedToSize:CGSizeMake(label.frame.size.width, MAXFLOAT)
lineBreakMode:UILineBreakModeWordWrap];
if(sz.width <= linesSz.width) //判断是否折行
{
lastPoint = CGPointMake(label.frame.origin.x + sz.width, label.frame.origin.y);
}
else
{
lastPoint = CGPointMake(label.frame.origin.x + (int)sz.width % (int)linesSz.width,linesSz.height - sz.height);
}
(3)注意,别忽略了一句代码,他表示不限制文本折行,少了这句,你的文本全显示在一行上,
textLabel.numberOfLines = 0;
资源上传:http://download.csdn.net/download/u013929312/7600505