iOS Socket 简单即时通讯
本位将简单实现一下循环接受数据的实现.对Socket不做过多解释,了解Socket实现了循环接受数据 www.jianshu.com/p/05b51c7555fe
首先导入头文件
#import<sys/socket.h>
#import<netinet/in.h>
#import<arpa/inet.h>
#import<ifaddrs.h>
#import<net/if.h>
@property (weak, nonatomic) IBOutlet UITextField *sendtext; @property (weak, nonatomic) IBOutlet UILabel *receiveLabel; @property(nonatomic,assign)int Mysocket; @property (nonatomic, strong) dispatch_source_t timer;
#define IOS_CELLULAR @"pdp_ip0"
#define IOS_WIFI @"en0"
#define IP_ADDR_IPv4 @"ipv4"
#define IP_ADDR_IPv6 @"ipv6"
//接下来,通过GCD定时器,实现循环接收数据,代码有点长,但是应该能用
- (void)viewDidLoad {
[super viewDidLoad];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 创建一个定时器(dispatch_source_t本质还是个OC对象)
self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC));
uint64_t interval = (uint64_t)(0.1 * NSEC_PER_SEC);
dispatch_source_set_timer(self.timer, start, interval, 0);
// 接受服务器请求链接
dispatch_source_set_event_handler(self.timer, ^{
struct sockaddr_in servAddr;
// 是Ipv4还是Ipv6做出相应更改Ipv6是AF_INET6
servAddr.sin_family = AF_INET;
// 端口号
servAddr.sin_port = htons(12345);
// 设备的IP地址
servAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
unsigned int nAddrlen = sizeof(servAddr);
int sClient = accept(self.Mysocket, (struct sockaddr *)&servAddr,&nAddrlen);
if (sClient==0) { NSLog(@"接受链接成功"); } else{ // NSLog(@"接受链接失败%d",sClient); return ;
}
});
// 接收服务器发送的数据
dispatch_source_set_event_handler(self.timer, ^{
uint8_t butter[1024];
ssize_t recvlen = recv(self.Mysocket, butter, sizeof(butter), 0);
if (recvlen <= 0) { return ; }
else{
NSString * mystr = [NSString stringWithUTF8String:butter];
NSLog(@"%@",mystr);
memset(butter, 0, sizeof(butter));
// 关闭socket
// close(self.Mysocket);
}
});
dispatch_resume(self.timer);
}
//发送消息按钮点击事件!发送消息相关
- (IBAction)sendbutt:(id)sender {
self.Mysocket = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in servAddr;
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(12345);
servAddr.sin_addr.s_addr = inet_addr("192.168.2.1");
int connetRect = connect(self.Mysocket, (const struct sockaddr *)&servAddr, sizeof(servAddr));
if (connetRect ==0) { NSLog(@"链接成功"); }else{ NSLog(@"链接失败%d",connetRect); return; }
NSString * strText = self.sendtext.text; ssize_t mySendLen = send(self.Mysocket, strText.UTF8String, strlen(strText.UTF8String), 0); NSLog(@"发送%zd字节",mySendLen);
// close(self.Mysocket);
}
//获取IP地址(本机IP地址)调用该方法,会直接得到本机的IP
- (NSDictionary *)getIPAddresses{
NSMutableDictionary *addresses = [NSMutableDictionary dictionaryWithCapacity:8];
// retrieve the current interfaces - returns 0 on success
struct ifaddrs *interfaces;
if(!getifaddrs(&interfaces)) { // Loop through linked list of interfaces struct ifaddrs *interface; for(interface=interfaces; interface; interface=interface->ifa_next) { if(!(interface->ifa_flags & IFF_UP) /* || (interface->ifa_flags & IFF_LOOPBACK) */ ) { continue; // deeply nested code harder to read }
const struct sockaddr_in *addr = (const struct sockaddr_in*)interface->ifa_addr; char addrBuf[ MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) ];
if(addr && (addr->sin_family==AF_INET || addr->sin_family==AF_INET6)) {
NSString *name = [NSString stringWithUTF8String:interface->ifa_name];
NSString *type;
if(addr->sin_family == AF_INET) { if(inet_ntop(AF_INET, &addr->sin_addr, addrBuf, INET_ADDRSTRLEN)) { type = IP_ADDR_IPv4; } } else { const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*)interface->ifa_addr; if(inet_ntop(AF_INET6, &addr6->sin6_addr, addrBuf, INET6_ADDRSTRLEN)) { type = IP_ADDR_IPv6;
}
}
if(type) { NSString *key = [NSString stringWithFormat:@"%@/%@", name, type]; addresses[key] = [NSString stringWithUTF8String:addrBuf];
}
}
}
// Free meory
freeifaddrs(interfaces);}
return [addresses count] ? addresses : nil; }
能力有限,只能写这么多.有什么问题欢迎大家留言指正,我看到一定回复.感谢!!!!!!!