mac 端口扫描-mac下端口扫描工具

hacker|
215

我的电脑有AMD网络唤醒功能,但是我是接在路由器下面的电脑,可以实现网络唤醒吗?怎么设置?

怎样实现网络唤醒开机

如果用户想通过网络唤醒一台指定的计算机,首先需要知道能标识该计算机的身份号。由于被唤醒的计算机处于关机状态,也就没有了IP地址和计算机名字,唯一能标识其身份的只有内部网卡的物理地址,即MAC地址,该地址是唯一的,而且每块网卡的MAC地址均不相同。

当用户知道被唤醒的计算机MAC地址后,通过另外一台计算机执行相应的软件,向网络上发出含有该地址的特殊数据包。此时,被唤醒的计算机虽然处于关机状态,但是其内部网卡控制芯片通过专用连线所送来的电流,仍然可以接收和处理网络上的数据包。因此控制芯片通过检查数据包内的MAC地址,就可确认自己就是该数据包的收件者,然后通过专用连线发出开机信号,通知主板开机启动。

硬件需求

应用网络唤醒开机功能必须要有相应的硬件支持才可使用。

首先要有主板支持。现在,新一代的主板大都支持网络唤醒功能,而且在主板上都有一个三脚插座,它一般在PCI插槽附近,旁边标注“WOL”。

其次必须要有网卡支持。这类网卡在主板上比一般的网卡多了一个三脚插座,并且通常还附带一条专用的三芯连接线,该线是用来连接主板和网卡之间的三脚插座。

最后还必须要使用ATX电源,而且其+5V Standby电流必须比较大,根据Intel的建议,它需要在600mA以上。该电流的大小可以从电源外部标识中的+5VSB栏里查到。

需要说明的是,某些主板上已经集成了具有网络唤醒功能的网卡,所以也就没有什么三脚插座,更不需要专用的三芯连线。

软件需求

为了唤醒网络上的计算机,用户必须发出一种数据包,该数据包的格式与普通数据包不同,而且还必须使用相应的专用软件才能产生。当前比较普遍采用的是AMD公司制作的Magic Packet,这套软件可以生成网络唤醒所需要的特殊数据包。该数据包包含有连续6个字节的“FF”和连续重复16次的MAC地址。Magic Packet 虽然只是AMD公司开发推广的一项技术,并非业界公认的标准,但是仍受到很多网卡制造商的支持,因此许多具有网络唤醒功能的网卡都能与之兼容。

2首先拨通自己家的ADSL,然后用ipconfig命令查看自己的Ip,如下图所示:

在开始-运行-输入cmd,在出现的dos窗口中输入ipconfig即可看到:

一般北京的ADSL上网的用户多为61.49.*.*。获得了自己的IP段之后,就可以找一个好的端口扫描工具了。新在端口扫描工具有很多,其中支持多线程、体积小、速度快的首推superscan。我们这里就使用它作为示范工具。Superscan的界面如下:

一般我们在开始地址处输入自己的IP段首地址,即61.49.*.1,结束IP地址会自动显示出61.49.*.254,这里需要说明的是,旁边那个ping,以及connect数据需要根据自己的情况输入,对于本网段的IP,即IP地址前3部分与自己的IP地址相同的IP,在扫描的时候可以把这些数据设置的短小一些,而对于其他网段的地址,一般需要设置的大一点。具体情况根据扫描结果而定,如果输入的数据太小,扫描之后会找不到计算机。

下面需要设置一下扫描端口,我们在探测路由器的时候只需要扫描80端口即可。所以单击窗体右上的配置列表,会出现如下窗体:

修改select

ports如图所示,去掉所有其他端口前的绿钩,(单击该端口即可)最终只保留80端口,然后单击save,把端口配置表保存到硬盘上,以后每次使用superscan的时候就不再需要从新配置,只需要load即可。

全部设置好之后,单击start进行扫描。扫描结束之后,如图所示:

我们可以看到这个网段有两台机器打开了80端口,单击这两台机器左边的小+号图标,可以显示这两台机器所开发的端口信息。61.49.150.68这台机器开放的是一个IIS的服务器,61.49.150.85这台机器开的是一个302标志,根据经验,我们可以知道这里开放的是一个中兴系列的路由器配置接口。本篇文章我们主要介绍ADSL路由器的安全隐患,IIS的安全性问题我们在后面的文章再介绍,这里我们只需在61.49.150.85上单击右键,选择web方式浏览即可。

单击之后会出现一个连接配置对话框,

点击OK,就可以连接了。连接之后弹出的提示框

通过刚才连接页上的标志,我们可以肯定这是一台中兴831路由器,输入出厂默认的用户名、密码:ZXDSL、ZXDSL,就进入了配置界面:

点击导航栏上的“quick configuration”就进入了快速配置界面,如图所示:

用户名已经看到了,密码却显示为小黑点,这怎么办呢,其实也难不倒大家,单击右键,选择查看源代码:

至此一个ADSL账户就被轻易盗取了。

其实补上这个漏洞的方法非常简单,只要用户在安装路由器的时候修改自己默认的密码即可了,但是很多人都没有去做这一步,为黑客留下了很多“靶子”。

路由器品牌

默认IP

默认账号

默认密码

TP LINK TD8800

192.168.1.1

root

root

TPLINK 8830

192.168.10.200

root

Root

TP LINK R410

192.168.1.1

admin

admin

中兴831

192.168.1.1

ZXDSL

ZXDSL

Cyrix686 D-Link DT704P

192.168.0.1

admin

admin

D-Link DSL-500

10.1.1.1

admin

admin

腾达TED 8620

192.168.1.1

admin

admin

阿尔卡特SPEEDTOUCH HOME PLUS 511E

10.0.0.138

root

root

SPEEDTOUCH 500

10.0.0.138

admin

admin

topstar 顶星TE-SR400

192.168.62.1

admin

admin

eTEK

伊泰克 TD-2001

192.168.1.1

admin

admin

我们把一些常见的路由器配置口令和IP地址公布一下,希望大家根据自己的路由器品牌进行甄别,修改默认的口令。

需要说明的是,这些数据都不是什么机密,它们就印在产品的说明书上面,所以我们强烈建议路由方式上网的ADSL用户赶快修改你们的密码,不要为不法之徒留下犯罪的空间。

如何高效实现扫描局域网IP,主机名,MAC和端口

免费的软件是肯定没有的. 如果是收费的话,应该可以.扫描IP这个不是什么技术难题,关键是扫描了之后对设备进行识别就比较麻烦.可以考虑采用C/S模式的软件,C端对设备进行识别,然后跟S端进行通讯,可以良好地解决这个问题.

Sp端口有哪几种?各端口的作用是什么?

nmap 使用介绍nmap是目前为止最广为使用的国外端口扫描工具之一。我们可以从 进行下载,可以很容易的安装到Windows和unix操作系统中,包括mac os x(通过configure、make 、make install等命令)也可以直接从http://下载windows二进制(包括所需要的winpcap)也可以从http://获得nmap的图形windows。扫描主机$ nmap -sT 192.168.1.18 Starting nmap 3.48( )at 2007-10-10 18:13 EDT Interesting ports on gamebase(192.168.1.18) port state serverice 22/tcp open ssh 111/tcp open sunrpc .......... $ nmap -sR 192.168.1.18 Startingnmap 3.48( )at 2007-10-10 18:13 EDT Interesting ports on gamebase(192.168.1.18) port state serverice 22/tcp open ssh 111/tcp open sunrpc ..........我们可以使用ping扫描的方法(-sP),与fping的工作方式比较相似,它发送icmp回送请求到指定范围的ip地址并等待响应。现在很多主机在扫描的时候都做了处理,阻塞icmp请求,这种情况下。nmap将尝试与主机的端口80进行连接,如果可以接收到响应(可以是syn/ack,也可以是rst),那么证明主机正在运行,反之,则无法判断主机是否开机或者是否在网络上互连。扫描tcp端口这里-sR是怎样在打开的端口上利用RPC命令来判断它们是否运行了RPC服务。nmap可以在进行端口扫描的tcp报文来做一些秘密的事情。首先,要有一个SYN扫描(-sS),它只做建立TCP连接的前面一些工作,只发送一个设置SYN标志的TCP报文,一个RESET报文,那么nmap假设这个端口是关闭的,那么就不做任何事情了。如果接收到一个响应,它并不象正常的连接一样对这个报文进行确认,而是发送一个RET报文,TCP的三次握手还没有完成,许多服务将不会记录这次连接。有的时候,nmap会告诉我们端口被过滤,这意味着有防火墙或端口过滤器干扰了nmap,使其不能准确的判断端口是打开还是关闭的,有的防火墙只能过滤掉进入的连接。扫描协议如果试图访问另一端无程序使用的UDP端口,主机将发回一个icmp“端口不可达”的提示消息,IP协议也是一样。每个传输层的IP协议都有一个相关联的编号,使用最多的是ICMP(1)、TCP(6)和UDP(17)。所有的IP报文都有一个“协议”域用于指出其中的传输层报文头所使用的协议。如果我们发送一个没有传输层报文头的原始IP报文并把其协议域编号为130[该编号是指类似IPSEC协议的被称为安全报文外壳或SPS协议],就可以判断这个协议是否在主机上实现了。如果我们得到的是ICMP协议不可达的消息,意味着该协议没有被实现,否则就是已经实现了,用法为-sO.隐蔽扫描行为nmap给出了几个不同的扫描选项,其中一些可以配套着隐藏扫描行为,使得不被系统日志、防火墙和IDS检测到。提供了一些随机的和欺骗的特性。具体例子如下:FTP反弹,在设计上,FTP自身存在一个很大的漏洞,当使用FTP客户机连接到FTP服务器时,你的客户机在TCP端口21上与FTP服务器对话,这个TCP连接称为控制连接。FTP服务器现在需要另一条与客户机连接,该连接称为数据连接,在这条连接上将传送实际的文件数据,客户机将开始监听另一个TCP端口上从服务器发挥的数据连接,接下来执行一个PORT命令到服务器,告诉它建立一条数据连接到客户机的IP地址和一个新打开的端口,这种操作方法称为主动传输。许多客户机使用网络地址转换或通过防火墙与外界连接,所以主动传输FTP就不能正常工作,因为由服务器建立的客户机的连接通常不允许通过。被动传输是大多数FTP客户机和服务器所使用的方法,因为客户机既建立控制连接又建立数据连接,这样可以通过防火墙或NAT了。FTP的PORT命令,用来告诉FTP连接的服务器,使得与刚刚打开的用于数据连接的端口之间建立一个连接。由于我们不仅指定端口而且指定连接所用的IP地址,所以客户端也可以通过PORT命令让服务器连接到任何地方。所以我们一样可以让nmap用这个方法进行防火墙穿透。nmap做的所有工作是与一台服务器建立一个主动模式的FTP连接,并发送一个包含它试图扫描的主机IP地址和端口号的PORT命令。nmap -b aaa@ -p 6000 192.168.1.226

nmap 与ftp服务器的对话的例子:

server:220 target ftp server version 4 ready

client:user anonymous

server: 331 Guest login ok ,send e-mail as password

client:pass

server :230 login successful

client:PORT 192,168,1.226,23,112

server:200 PORT command successful

client:LIST

server:150 Opening ASCII connection for '/bin/ls'

server:226 Transfer completePORT命令起作用,可以制造是别人进行端口扫描,扫描任何FTP服务器所能访问的主机,绕过防火墙和端口过滤器,但还是存在一些危险的,如果对方登陆到了你的这个匿名FTP服务器上,从日志查找到相应的匿名FTP连接,从而知道你的IP地址,这样就直接暴露了。nmap -sI 空闲扫描,主要是欺骗端口扫描的源地址。nmap -f 可以把TCP头分片的IP报文进行一些隐蔽的扫描。不完整的TCP报文不被防火墙阻塞也不被IDS检测到。nmap-D

选择几台肉鸡,并使用-D标志在命令行中指定它们。namp通过诱骗的IP地址来进行欺骗式端口扫描,而系统管理员可以同时看到不同的端口扫描,而只有一个是真实的,很好的保护了自己。os指纹识别

这个是nmap最有用的功能之一,就是可以鉴别远程主机。通过简单的执行网络扫描,nmap通常可以告诉你远程主机所运行的OS,甚至详细到版本号。当你指定-Q标志时,nmap将用几种不同的技术从主机返回IP报文中寻找这些鉴别信息。通过发送特别设计的TCP和UDP头,nmap可以得到远程主机对TCP/IP协议栈的处理方法。它将分析结果与保存在文件中的已知特征信息进行比较。OS鉴别选项也可以让nmap对TCP报文进行分析以决定另外一些信息,如系统的启动时间,TCP序列号,预测的序列号使我们更容易截获报文并猜测序列号从而伪造TCP连接。nmap命令使用详细解释-P0 -PT -PS -PU -PE -PP -PM -PB 当nmap进行某种类型的端口或协议扫描时,通常都会尝试先ping 主机,这种尝试可使nmap不会浪费时间在那些未开机的主机上,但是许多主机与防火墙会阻塞ICMP报文,我们希望能通过控制使用。-P0 告诉nmap不ping 主机,只进行扫描-PT 告诉nmap使用TCP的ping-PS 发送SYN报文。-PU 发送一个udp ping-PE 强制执行直接的ICMP ping -PB 这是默认类型,可以使用ICMP ping 也可以使用TCP ping .-6 该标志允许IPv6支持-v -d 使用-v选项可得到更详细的输出,而-d选项则增加调试输出。-oN 按照人们阅读的格式记录屏幕上的输出,如果是在扫描多台机器,则该选项很有用。-oX 以xml格式向指定的文件记录信息-oG 以一种易于检索的格式记录信息,即每台主机都以单独的行来记录所有的端口和0s信息。-oA 使用为基本文件名,以普通格式(-oN)、XML格式(-oX)和易于检索的格式(-oG)jilu xinxi -oM 把输出格式化为机器可阅读的文件-oS 把输出进行傻瓜型排版--resume如果你取消了扫描,但生成了供人或者供机器阅读的文件,那么可以把该文件提供给nmap继续让它扫描。-iR-iL可以不在命令行中指定目标主机,而是使用-iR选项随即产生待扫描的主机,或者使用-iL选项从一个包含主机名或IP地址列表的文件中读取目标主机,这些主机名或IP地址使用空格、制表符或换行隔开。-F nmap只扫描在nmap内建的服务文件中已知的端口,如果不指定该选项,nmap将扫描端口1-1024及包含在nmap-services文件中的所有其他端口。如果用-sO选项扫描协议,nmap将用它内建的协议文件(nmap-protocols文件)而不是默认地扫描所有256个协议。-A nmap使用所有的高级扫描选项-p 参数可以是一个单独的端口、一个用逗号隔开的端口列表、一个使用“-”表示的端口范围或者上述格式的任意组合。如果没有指定该选项,nmap将对包含前1024个端口的所有端口进行一次快速扫描。-e在多穴主机中,可以指定你用来进行网络通信的网络接口。-g可以选择一个源端口,从该端口执行所有的扫描。--ttlnmap其发送的任何报文在到中间路由器的跳后会失效。--packet-trace 可以显示扫描期间nmap发送和接收的各个报文的详细列表,这对调试非常有用。要与-o选项之一联合使用,需要根权限,以将所有的数据记录到文件。--scanflags可以使用这个选项手工的指定欲在扫描报文中设置的TCP标志。也可以指定TCP标志的OOred值的整数形式,或者标志的字符串表示形式。以上介绍的就是nmap在windows下和unix中的命令介绍。

mac查看端口占用该怎么操作

点击窗口中的“网络实用工具”。

在打开的“网络实现工具”中,选择“端口扫描”标签。

然后输入本机IP地址去扫描开放的接口。下图中就会列出本机开放的端口及占用情况。

mac上如何查看某端口号被哪些程序占用

你好,

可以使用“网络实用工具”,它是苹果自带的网络分析工具

系统版本在10.8之前的位于 launchpad -- 其他-- 网络实用工具

系统版本在10.9之后隐藏了该应用,但可以通过 spotlight 搜索“网络实用工具”或者点击屏幕最左上角的苹果标志 -- 关于本机 --点按'系统报告' -- 标题栏的'窗口' -- 网络实用工具 -- 点按'端口扫描',输入127.0.0.1,点击扫描。(可以指定扫描端口)

mac上怎么连接到socket

一、建立socket链接,Mac端终端使用nc命令做端口监听,oc作为客户端建立socket连接。

使用的工具及使用方法:

nc/netcat(选项)(参数)

-g网关:设置路由器跃程通信网关,最多设置8个;

-G指向器数目:设置来源路由指向器,其数值为4的倍数;

-h:在线帮助;

-i延迟秒数:设置时间间隔,以便传送信息及扫描通信端口;

-l:使用监听模式,监控传入的资料;

-n:直接使用ip地址,而不通过域名服务器;

-o输出文件:指定文件名称,把往来传输的数据以16进制字码倾倒成该文件保存;

-p通信端口:设置本地主机使用的通信端口;

-r:指定源端口和目的端口都进行随机的选择;

-s来源位址:设置本地主机送出数据包的IP地址;

-u:使用UDP传输协议;

-v:显示指令执行过程;

-w超时秒数:设置等待连线的时间;

-z:使用0输入/输出模式,只在扫描通信端口时使用。

1、服务端 端口监听

nc -l 6666

2、永久监听TCP端口

nc -lk port

3、临时监听UDP

nc -lu port

4、永久监听UDP

nc -luk port

5、连接服务端

nc -v 127.0.0.1 666

6、端口扫描

nc -v -w 1 127.0.0.1 -z 1-1000

客户端代码:

#import "ViewController.h"

#import sys/socket.h

#import arpa/inet.h//inet_addr

#define connect_host @"127.0.0.1"

#define connect_port 6666

@interface ViewController (){

int clientSocket;

dispatch_queue_t queSerial;

}

@end

@implementation ViewController

- (void)viewDidLoad {

[super viewDidLoad];

//button

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];

button.frame = CGRectMake((self.view.frame.size.width-200)/2, 100, 200, 30);

button.backgroundColor = [UIColor grayColor];

[button setTitle:@"发送普通文本" forState:UIControlStateNormal];

[button addTarget:self action:@selector(btn:) forControlEvents:UIControlEventTouchUpInside];

[self.view addSubview:button];

button = [UIButton buttonWithType:UIButtonTypeCustom];

button.frame = CGRectMake((self.view.frame.size.width-200)/2, 150, 200, 30);

button.backgroundColor = [UIColor grayColor];

[button setTitle:@"发送图片" forState:UIControlStateNormal];

[button addTarget:self action:@selector(btn:) forControlEvents:UIControlEventTouchUpInside];

[self.view addSubview:button];

button = [UIButton buttonWithType:UIButtonTypeCustom];

button.frame = CGRectMake((self.view.frame.size.width-200)/2, 200, 200, 30);

button.backgroundColor = [UIColor grayColor];

[button setTitle:@"发送文本加图片" forState:UIControlStateNormal];

[button addTarget:self action:@selector(btn:) forControlEvents:UIControlEventTouchUpInside];

[self.view addSubview:button];

[self initSocket];

}

-(void)btn:(UIButton *)button{

if ([button.titleLabel.text isEqualToString:@"发送普通文本"]) {

[self sendMessage:@"发送普通文本"];

}else if ([button.titleLabel.text isEqualToString:@"发送图片"]) {

UIImage *image = [UIImage imageNamed:@"hibo"];

NSData *data = UIImagePNGRepresentation(image);

NSLog(@"height:%f",image.size.height);

NSString *dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

NSLog(@"%@",dataString);

// [self sendMessage:dataString];

}else if ([button.titleLabel.text isEqualToString:@"发送文本加图片"]) {

}

}

//发起socket连接

-(BOOL)initSocket{

/*

第一个参数:adress_family,协议簇 AF_INET:IPV4

第二个参数:数据格式-SOCK_STREAM(TCP)/SOCK_DGRAM(UDP)

第三个参数:protocal IPPROTO_TCP,如果为0会根据第二个参数选择合适的协议

返回值:0成功 -1失败

*/

clientSocket = socket(AF_INET, SOCK_STREAM, 0);

NSLog(@"clientsocket:%d",clientSocket);

if (clientSocket0) {

NSLog(@"socket create success");

}else{

NSLog(@"socket create error");

}

/*

连接

第一个参数:客户端socket

第二个参数:指向数据结构,socketAddr的指针,其中包括目的端口和IP地址

第三个参数:结构体数据长度

返回值:0成功 其他错误

*/

struct sockaddr_in addr4 = {0};

addr4.sin_family = AF_INET;//ipv4

addr4.sin_len = sizeof(addr4);

addr4.sin_addr.s_addr = inet_addr(connect_host.UTF8String);

addr4.sin_port = htons(connect_port);//是将整型变量从主机字节顺序转变成网络字节顺序, 就是整数在地址空间存储方式变为高位字节存放在内存的低地址处

int flag = connect(clientSocket, (const struct sockaddr *)addr4, sizeof(addr4));

if (!flag) {

[self receiveMessage];

}else{

clientSocket = 0;

NSLog(@"连接失败");

}

return flag;

}

//接收消息

-(void)receiveMessage{

if (!queSerial) {

queSerial=dispatch_queue_create("jrQueueSerial", DISPATCH_QUEUE_SERIAL);

}

dispatch_async(queSerial, ^{

uint8_t buffer[1024];

ssize_t recvLen = recv(self-clientSocket, buffer, sizeof(buffer), 0);

NSData *data = [NSData dataWithBytes:buffer length:recvLen];

NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

if (recvLen0) {

NSLog(@"%@:%@",str,[NSThread currentThread]);

NSLog(@"%@",str);

[self receiveMessage];

}else{

NSLog(@"连接断开");

self-clientSocket = 0;

}

});

}

//发送消息

-(BOOL)sendMessage:(NSString *)message{

if (clientSocket==0) {

BOOL flag = [self initSocket];

if (!flag)return NO;

}

ssize_t sendLen = send(clientSocket, message.UTF8String, strlen(message.UTF8String), 0);

NSLog(@"发送消息长度:%zd",sendLen);

return sendLen=0;

}

@end

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

1、在终端执行命令监听端口6666:

nc -l 127.0.0.1 6666

1

1

进入等待连接状态。

2、执行以上oc代码进行socket连接:

client_socket.png

3、以上连接成功,由服务端发送一条消息,客户端接收打印如下:

client_receive.png

注:以上代码中图片发送及文本+图片发送未完成。

二、oc模拟服务端代替Mac终端命令,一步步实现服务端的三次握手及通信。主要使用方法:

1、创建一个socket:

socket(AF_INET, SOCK_STREAM, 0);

1

1

第一个参数:address_family,协议簇 AF_INET对应的IPV4;

第二个参数:数据格式可选两种SOCK_STREAM(TCP)、SOCK_DGRAM(UDP);

第三个参数:protocal IPPROTO_TCP,设置为0会根据第二个参数选择相应的协议;

返回值:sockaddr -1失败 其他成功为socket标号1、2、3、 4,指示为当前socket。

2、端口绑定:

bind(sockaddr, (const struct sockaddr *)addr4, sizeof(addr4));

1

1

第一个参数:创建的socket描述号;

第二个参数:对应socketaddr_in(对应IPV4)的结构体包含了端口号;

第三个参数:socketaddr_in结构体长度。

3、监听端口:

listen(sockaddr, 5);

1

1

第一个参数:创建的socket标号;

第二个参数:可以排队的最大连接个数。

4、获取连接的socket标号和以上使用的标号不同

accept(sockaddr, (struct sockaddr *)aptsockaddr, addrLen);

1

1

第一个参数:创建的socket描述号;

第二个参数:可以排队的最大连接个数;

返回值:接收后的socket标号。

5、接收客户端消息:

recv(aptsocket, buffer, len, 0);

1

1

第一个参数:accept返回的标号理解为当前socket;

第二个参数:接收字符的缓存变量;

第三个参数:一般设置0;

返回值:接收到的数据长度。

6、发送消息:

send(aptsocket, message.UTF8String, strlen(message.UTF8String), 0);

1

1

第一个参数:accept返回的标号理解为当前socket;

第二个参数:发送的消息字符char *型数据;

第三个参数:一般设置0;

返回值:发送的数据长度。

服务端代码:

/*

ipv6

struct sockaddr_in6 addr6 = {0};

bzero(addr6, sizeof(addr6));

addr6.sin6_len = sizeof(addr6);

addr6.sin6_family = AF_INET6;

addr6.sin6_port = htons(connect_port);

htons将主机的无符号短整形数转换成网络字节顺序

htonl将主机的无符号长整形数转换成网络字节顺序

*/

#import "ViewController.h"

#import sys/socket.h

#import arpa/inet.h//inet_addr

#define connect_host @"127.0.0.1"

#define connect_port 6666

@interface ViewController ()

{

int sockaddr;//创建的socket地址

int aptsocket;//同意后返回的socket地址

dispatch_queue_t queSerial;//接收消息的队列

BOOL socket_flag;//socket标识

}

@end

@implementation ViewController

- (void)viewDidLoad {

[super viewDidLoad];

//button

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];

button.frame = CGRectMake((self.view.frame.size.width-200)/2, 100, 200, 30);

button.backgroundColor = [UIColor grayColor];

[button setTitle:@"回复文本" forState:UIControlStateNormal];

[button addTarget:self action:@selector(btn:) forControlEvents:UIControlEventTouchUpInside];

[self.view addSubview:button];

button = [UIButton buttonWithType:UIButtonTypeCustom];

button.frame = CGRectMake((self.view.frame.size.width-200)/2, 150, 200, 30);

button.backgroundColor = [UIColor grayColor];

[button setTitle:@"关闭链接" forState:UIControlStateNormal];

[button addTarget:self action:@selector(btn:) forControlEvents:UIControlEventTouchUpInside];

[self.view addSubview:button];

button = [UIButton buttonWithType:UIButtonTypeCustom];

button.frame = CGRectMake((self.view.frame.size.width-200)/2, 200, 200, 30);

button.backgroundColor = [UIColor grayColor];

[button setTitle:@"创建链接" forState:UIControlStateNormal];

[button addTarget:self action:@selector(btn:) forControlEvents:UIControlEventTouchUpInside];

[self.view addSubview:button];

//创建服务端socket

[self initServerSocket];

}

-(void)btn:(UIButton *)button{

if ([button.titleLabel.text isEqualToString:@"回复文本"]) {

[self sendMessage:@"回复:你好啊!!"];

}else if ([button.titleLabel.text isEqualToString:@"关闭链接"]) {

[self closeSocket];

}else if ([button.titleLabel.text isEqualToString:@"创建链接"]) {

[self initServerSocket];

}

}

//初始化socket

-(BOOL)initServerSocket{

socket_flag = YES;

//1、创建一个socket

sockaddr = socket(AF_INET, SOCK_STREAM, 0);

NSLog(@"sockaddr:%d",sockaddr);

if (sockaddr==-1) {

NSLog(@"创建失败");

return NO;

}

//ipv4

struct sockaddr_in addr4 = {0};

//参数说明:s 要置零的数据的起始地址; n 要置零的数据字节个数。

memset(addr4, 0, sizeof(addr4));

addr4.sin_len = sizeof(addr4);

addr4.sin_family = AF_INET;

addr4.sin_port = htons(connect_port);//将主机的无符号短整形数转换成网络字节顺序

addr4.sin_addr.s_addr = INADDR_ANY;//就是指定地址为0.0.0.0的地址,这个地址事实上表示不确定地址,或“所有地址”、“任意地址”

//2、端口绑定

int error = bind(sockaddr, (const struct sockaddr *)addr4, sizeof(addr4));

if (error!=0) {

NSLog(@"绑定失败");

return NO;

}

//3、监听端口

error = listen(sockaddr, 5);//开始监听第二个参数可以排队的最大连接个数

if (error!=0) {

NSLog(@"监听失败");

return NO;

}

//4、轮询

if (!queSerial) {

queSerial = dispatch_queue_create("receive_queue", DISPATCH_QUEUE_SERIAL);

}

dispatch_async(queSerial, ^{

[self receiveMessage];

});

return YES;

}

//轮询接收消息

-(void)receiveMessage{

while (true) {

NSLog(@"currentThread:%@",[NSThread currentThread]);

struct sockaddr_in aptsockaddr;

socklen_t addrLen = sizeof(aptsockaddr);

//4、获取连接的socket

aptsocket = accept(sockaddr, (struct sockaddr *)aptsockaddr, addrLen);

NSLog(@"aptsocket:%d",aptsocket);

if (aptsocket != -1) {

NSLog(@"accept success address:%ss, port:%d",inet_ntoa(aptsockaddr.sin_addr),ntohs(aptsockaddr.sin_port));

char buffer[1024];

ssize_t recvLen;

size_t len = sizeof(buffer);

do{

//5、接收客户端的消息

recvLen = recv(aptsocket, buffer, len, 0);

NSString *str = [NSString stringWithCString:buffer encoding:NSUTF8StringEncoding];

NSLog(@"receive:%@",str);

NSLog(@"buffer:%s",buffer);

[self sendMessage:@"回复你:哈哈"];

}while(socket_flag);

}

close(aptsocket);

break;//链接失败后跳出轮询

}

}

//发送消息

-(BOOL)sendMessage:(NSString *)message{

if (sockaddr==0) {

NSLog(@"链接已断开");

}

ssize_t sendLen = send(aptsocket, message.UTF8String, strlen(message.UTF8String), 0);

NSLog(@"发送消息长度:%zd",sendLen);

return sendLen=0;

}

//断开链接

-(void)closeSocket{

NSLog(@"关闭链接");

socket_flag = NO;

}

@end

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

通过以上过程,对socket通信能有一个初步了解,可以利用socket通信搭建一套简单的聊天系统

0条大神的评论

发表评论