客户端
在项目中导入 IPAddress.h, IPAddress.c 这两个类
导入相应的头文件
#import <UIKit/UIKit.h>
#import <sys/types.h>
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>
#import <stdio.h>
#import <stdlib.h>
#import <string.h>
#import <unistd.h>
#import <netdb.h>
#import "IPAddress.h"
实现代码如下
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.navigationController.navigationBar.translucent = NO;
[self setBtn];
//[self createConnect];
}
-(void)setBtn
{
_IPtextField = [[UITextField alloc] initWithFrame:CGRectMake(20, 20, 280, 40)];
_IPtextField.delegate = self;
_IPtextField.borderStyle = UITextBorderStyleRoundedRect;
_IPtextField.placeholder = @"ip地址";
_IPtextField.text = @"192.168.2.121";
[self.view addSubview:_IPtextField];
_textField = [[UITextField alloc] initWithFrame:CGRectMake(20, 80, 280, 40)];
_textField.delegate = self;
_textField.borderStyle = UITextBorderStyleRoundedRect;
_textField.placeholder = @"请输入发送消息";
[self.view addSubview:_textField];
_textView = [[UITextView alloc] initWithFrame:CGRectMake(20, 140, 280, 100)];
_textView.delegate = self;
_textView.backgroundColor = [UIColor lightGrayColor];
[self.view addSubview:_textView];
_btn1 = [UIButton buttonWithType:UIButtonTypeSystem];
_btn1.frame = CGRectMake(30, 250, 80, 40);
[_btn1 setTitle:@"连接" forState:UIControlStateNormal];
[_btn1 setTitle:@"断开" forState:UIControlStateSelected];
[_btn1 addTarget:self action:@selector(createThread) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_btn1];
UIButton *btn2 = [UIButton buttonWithType:UIButtonTypeSystem];
btn2.frame = CGRectMake(160, 250, 120, 40);
[btn2 setTitle:@"发送消息" forState:UIControlStateNormal];
[btn2 addTarget:self action:@selector(SendMessage) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn2];
}
//点击空白处收回键盘
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[_textField resignFirstResponder];
[_textView resignFirstResponder];
}
-(void)createThread
{
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(link) object:nil];
[thread start];
}
-(void)link
{
[self linkHost];
}
//连接服务器
- (void)linkHost
{
[_btn1 setSelected:!_btn1.selected];
if (_btn1.selected)
{
//创建socket
_SocketFD = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (-1 == _SocketFD)
{
perror("cannot create socket");
exit(1);
}
struct sockaddr_in addr4;
//初始化内存
memset(&addr4, 0, sizeof(addr4));
//设置socket地址协议族
addr4.sin_family = AF_INET;
//设置端口号
addr4.sin_port = htons(5000);
NSString *ipStr = _IPtextField.text;
const char *ipCString = [ipStr cStringUsingEncoding:NSUTF8StringEncoding];
int result = inet_pton(AF_INET, ipCString, &addr4.sin_addr);
//转换ip地址出错
if (result < 0) {
NSLog(@"转换错误");
close(_SocketFD);
exit(1);
}else if (result == 0){
NSLog(@"char string (second parameter does not contain valid ipaddress)");
close(_SocketFD);
exit(1);
}
result = connect(_SocketFD, (struct sockaddr *)&addr4, sizeof(addr4));
/* 出错处理 */
if (result == -1)
{
perror("connect failed");
close(_SocketFD);
exit(1);
}
while (1) {
//************
//建立数据缓冲区
char readBuffer[1024];
int br = 0;
while ((br = recv(_SocketFD, readBuffer, sizeof(readBuffer), 0)) < sizeof(readBuffer) && br != 0)
{
// NSLog(@"==========");
readBuffer[br] = '\0';
NSString *bufferString = [NSString stringWithCString:readBuffer encoding:NSUTF8StringEncoding];
[self performSelectorOnMainThread:@selector(receiveMessage:) withObject:bufferString waitUntilDone:NO];
memset(readBuffer, 0, 1024);
}
}
}
}
-(void)SendMessage
{
NSString *ipStr = @"192.168.2.110";
NSString *ipStr2 = @"192.168.2.134";
NSString *str = [ipStr stringByAppendingString:_textField.text];
const char *message = [str UTF8String];
//发送数据
send(_SocketFD, message, strlen(message), 0);
_textField.text = @"";
}
-(void)receiveMessage:(NSString *)string
{
string = [string stringByAppendingString:@"\n"];
[_textView insertText:string];
}
服务器端
同上导入相关的类和头文件
实现代码如下
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.navigationController.navigationBar.translucent = NO;
//_dic = [NSDictionary dictionary];
[self setBtn];
}
-(void)setBtn
{
_textField = [[UITextField alloc] initWithFrame:CGRectMake(20, 20, 280, 40)];
_textField.delegate = self;
_textField.borderStyle = UITextBorderStyleRoundedRect;
_textField.placeholder = @"请输入发送消息";
[self.view addSubview:_textField];
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 190, 320, self.view.frame.size.height) style:UITableViewStylePlain];
_tableView.delegate = self;
_tableView.dataSource = self;
[self.view addSubview:_tableView];
_textView = [[UITextView alloc] initWithFrame:CGRectMake(100, 80, 200, 80)];
_textView.delegate = self;
_textView.backgroundColor = [UIColor lightGrayColor];
[self.view addSubview:_textView];
_btn1 = [UIButton buttonWithType:UIButtonTypeSystem];
_btn1.frame = CGRectMake(5, 80, 80, 40);
[_btn1 setTitle:@"启动服务器" forState:UIControlStateNormal];
[_btn1 setTitle:@"启动成功" forState:UIControlStateSelected];
[_btn1 addTarget:self action:@selector(createThread) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_btn1];
UIButton *btn2 = [UIButton buttonWithType:UIButtonTypeSystem];
btn2.frame = CGRectMake(5, 130, 80, 40);
[btn2 setTitle:@"发送消息" forState:UIControlStateNormal];
[btn2 addTarget:self action:@selector(SendMessage) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn2];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = @"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.textLabel.text = [_listArray[indexPath.row] stringValue];
return cell;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _listArray.count;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
_ConnectFD = [_listArray[indexPath.row] intValue];
}
//点击空白处收回键盘
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[_textField resignFirstResponder];
[_textView resignFirstResponder];
}
-(void)createThread
{
// NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(link) object:nil];
// [thread start];
[NSThread detachNewThreadSelector:@selector(linkHost) toTarget:self withObject:nil];
}
-(void)link
{
[self linkHost];
}
//连接服务器
- (void)linkHost
{
[_btn1 setSelected:!_btn1.selected];
if (_btn1.selected)
{
//创建socket
_SocketFD1 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (-1 == _SocketFD1)
{
perror("cannot create socket");
exit(1);
}
int yes = 1;
if (setsockopt(_SocketFD1, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
{
perror("setsockopt error!");
exit(1);
}
//创建Socket address结构体
struct sockaddr_in addr4;
//初始化内存
memset(&addr4, 0, sizeof(addr4));
//设置socket地址协议族
addr4.sin_family = AF_INET;
//设置端口号
addr4.sin_port = htons(5000);
//设置ip 地址
addr4.sin_addr.s_addr = htonl(INADDR_ANY);
//socket 套接字和指定的socket地址进行绑定
if (-1 == bind(_SocketFD1, (struct sockaddr *)&addr4, sizeof(addr4)))
{
NSLog(@"绑定地址失败");
close(_SocketFD1);
exit(1);
}
if (-1 == listen(_SocketFD1, 10))
{
NSLog(@"监听失败");
close(_SocketFD1);
exit(1);
}
while (1)
{
//创建Socket address结构体
struct sockaddr_in address;
unsigned int addr = sizeof(address);
_ConnectFD = accept(_SocketFD1,(struct sockaddr *)&address,&addr);
// NSLog(@"------------%u",addr);
//获取客户端的ip地址
char *str = inet_ntoa(address.sin_addr);
// NSLog(@"*****------%s",str);
NSString *ipstr = [[NSString alloc] initWithCString:str encoding:NSUTF8StringEncoding];
NSLog(@"*****%@",ipstr);
if (0 > _ConnectFD)
{
NSLog(@"接收失败");
close(_SocketFD1);
exit(1);
}else
{
if(!_listArray){
self.listArray = [NSMutableArray array];
}
if (!_ipArray) {
self.ipArray = [NSMutableArray array];
}
[_listArray addObject:[NSNumber numberWithInt:_ConnectFD]];
[_ipArray addObject:ipstr];
_dic = [[NSDictionary alloc] initWithObjects:_ipArray forKeys:_listArray];
NSLog(@"%@",_dic);
[_tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
[self performSelectorInBackground:@selector(aa:) withObject:[NSNumber numberWithInt:_ConnectFD]];
NSLog(@"接收成功");
}
}
}
}
-(void)aa:(NSNumber *)ConnectID
{
char readBuffer[1024];
int br = 0;
while ((br = recv([ConnectID intValue], readBuffer, sizeof(readBuffer), 0)) < sizeof(readBuffer)&& br != 0)
{
readBuffer[br] = '\0';
NSString *bufferString = [NSString stringWithCString:readBuffer encoding:NSUTF8StringEncoding];
if([_listArray count] > 1)
{
int current =[ConnectID intValue];
// int a =[_listArray[0] intValue];
// int b =[_listArray[1] intValue];
//NSLog(@"-------%@",bufferString);
//标准是客户端的发送内容前面是目标iP地址,拼接发送给目标的信息
static NSString * IPRegex = @"^(\\d{1,3}\\.){3}\\d{1,3}";//验证ip地址
NSError *error;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:IPRegex options:0 error:&error];
NSString *msgStr;
NSString *result;
if (regex != nil) {
NSTextCheckingResult *firstMatch=[regex firstMatchInString:bufferString options:0 range:NSMakeRange(0, [bufferString length])];
if (firstMatch) {
NSRange resultRange = [firstMatch rangeAtIndex:0];
NSLog(@"%lu",(unsigned long)resultRange.location);
//从urlString当中截取数据
result = [bufferString substringWithRange:resultRange];
//输出结果
NSLog(@"----------%@",result);//目标ip地址
msgStr = [bufferString substringFromIndex:resultRange.length];
NSLog(@"*******%@",msgStr); //发送的内容
}
}
const char * ch = [msgStr UTF8String];
for (int i = 0; i < _listArray.count; i++) {
int temp = [_listArray[i] intValue];
if (current != temp && [result isEqualToString:[_dic objectForKey:_listArray[i]]]) {
send(temp, ch, strlen(ch), 0);
}
}
// const char * ch = [bufferString UTF8String];
// if(current != a)
// send(a, ch, strlen(ch), 0);
// else
// send(b, ch, strlen(ch), 0);
}else{
send([ConnectID intValue],[bufferString UTF8String], strlen([bufferString UTF8String]), 0);
}
//[self performSelectorOnMainThread:@selector(updateReceiveView:) withObject:bufferString waitUntilDone:NO];
}
}
/* 获得本机ip */
- (NSString *)deviceIPAdress
{
InitAddresses();
GetIPAddresses();
GetHWAddresses();
return [NSString stringWithFormat:@"%s", ip_names[1]];
}
-(void)SendMessage
{
NSString *message = _textField.text;
const char *cmessage =[message UTF8String];
//[message cStringUsingEncoding:NSUTF8StringEncoding];
send(_ConnectFD, cmessage, strlen(cmessage), 0);
_textField.text = @"";
}
-(void)updateReceiveView:(NSString *)string
{
string = [string stringByAppendingString:@"\n"];
[_textView insertText:string];
}
实现简单的socket通信,不足之处还望大家理解与补充。
来源:oschina
链接:https://my.oschina.net/u/2011009/blog/349728