端口扫描程序_csocket端口扫描

hacker|
189

socket error:Error:read ECONNRESET.怎么回事

服务器错误, 端口扫描的问题 在写端口扫描时 ,如果与某主机特定端口无法通信 , 就此主机而言 ,我想应该有以下两种情况 : 1 。此地址上无任何主机存在 2 。有主机但被扫描的特定端口不存在 ( 也可能是被 firewall 过滤了 ) 如何得知某端口一打开.

windows socket error怎么解决

端口被占用了,下载个端口扫描器看看是哪个程序先占用了这个端口,控制面板中删除它。

利用socket判断哪些端口处于打开状态,可以设置被扫描主机的ip,设置开始和终止的端口号

Socket client = null;

try{

client = new Socket(IP, port);

System.out.println("端口已开放");

client.close();

}catch(Exception e){

System.out.println("端口未开放");

}

====================================================

这样就能正常捕获这个异常,不会阻止程序正常运行!

Asynchronous socket error 10061

服务器错误,

端口扫描的问题

在写端口扫描时 ,如果与某主机特定端口无法通信 ,

就此主机而言 ,我想应该有以下两种情况 :

1 。此地址上无任何主机存在

2 。有主机但被扫描的特定端口不存在 ( 也可能是被 firewall 过滤了 )

如何得知某端口一打开

给你来个简单的吧!

procedure TForm1.Timer1Timer(Sender: TObject);

var

I : integer;

begin

Memo1.Clear;

for I := 0 to 1000 do begin

ServerSocket1.Close;

ServerSocket1.Port := I;

try

ServerSocket1.Open;

except

Memo1.Lines.Add(IntToStr(I) + ' 端口被打开 !');

end;

end;

end;

对不起 ,我指的是别人机器上的 PORT

你是说 PORT 只能被一个程序打开么 ?

可是 ,我用 OICQ 时在打开 4000 没问题呀

我把上面的程序改了一下 ,也可以用的。你就去试图连接对方 ,如果通了 ,说明此端口被打

开。

procedure TForm1.ClientSocket1Connect(Sender: TObject;

Socket: TCustomWinSocket);

begin

Memo1.Lines.Add(' 端口 '+IntToStr(Socket.RemotePort)+' 被打开! ');

end;

procedure TForm1.Timer1Timer(Sender: TObject);

begin

ClientSocket1.Close;

ClientSocket1.Port := PortID;

try

ClientSocket1.Open;

except

end;

Inc(PortID);

end;

procedure TForm1.FormCreate(Sender: TObject);

begin

PortID := 1;

end;

procedure TForm1.ClientSocket1Error(Sender: TObject;

Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;

var ErrorCode: Integer);

begin

try

ClientSocket1.Close;

except

end;

Memo2.Lines.add(IntToStr(Socket.remotePort));

end;

吕雪松你的 *** 我试过了可是抱错 :asynchronous socket error 10061

--------------------------------------------------------------------------------

来自 :xueminliu 时间 :01-3-3 17:26:47 ID:464312

要区分 tcp 和 udp

oicq 用 udp 协议 ,connect 没有用 ,但是 tcp 可以这样

另外 ,如果你写扫描程序可千万不要这样 ,应该使用别的链接 *** ,否则你的踪迹会被别人

发现 .例如使用 sys 扫描或者 fin 扫描 :

我给你异步 socket 的 api 代码 :

unit Unit1;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

StdCtrls,WInSock, ExtCtrls;

const WM_SOCKET=WM_USER+1; //socket 消息

type

TForm1 = class(TForm)

Button1: TButton;

Edit1: TEdit;

Panel1: TPanel;

Memo1: TMemo;

procedure FormCreate(Sender: TObject);

procedure FormDestroy(Sender: TObject);

procedure Button1Click(Sender: TObject);

procedure Button2Click(Sender: TObject);

procedure Button3Click(Sender: TObject);

private

Sockhd : integer; //socket 句柄

Serv_Addr : Tsockaddr;// 目标地址

procedure SockEvent(var msg: Tmessage);message WM_SOCKET; // 处理 cocket 消息

procedure DspMsg(msg : string); // 显示信息

{ Private declarations }

public

{ Public declarations }

end;

Form1: TForm1;

implementation

{$R *.DFM}

function lookup_hostname(const hostname:string):longint; // 把域名转化成 IP 地址

var

RemoteHost : PHostEnt; (* no, don't free it! *)

ip_address: longint;

begin

ip_address:=-1;

try

if hostname='' then

begin (* no host given! *)

lookup_hostname:=ip_address;

EXIT;

end

else

begin

ip_address:=Winsock.Inet_Addr(PChar(hostname)); (* try a xxx.xxx.xxx.xx first *)

if ip_address=SOCKET_ERROR then begin

RemoteHost:=Winsock.GetHostByName(PChar(hostname));

if (RemoteHost=NIL) or (RemoteHost^.h_length=0) then

begin

lookup_hostname:=ip_address;

EXIT; (* host not found *)

end

else

ip_address:=longint(pointer(RemoteHost^.h_addr_list^)^);

end;

end;

except

ip_address:=-1;

end;

lookup_hostname:=ip_address;

end;

procedure TFOrm1.DspMsg(msg: string);

begin

memo1.Lines.Add(msg+'...');

if Memo1.Lines.Count200 then Memo1.Lines.Delete(0);

end;

procedure TForm1.SockEvent(var msg : tmessage); // 处理 socket 消息

begin

case msg.LParam of

FD_READ: begin // 标识可以读数据 ,当然肯定已经链接上了

dspmsg(' 可以读取数据 ');

//do what you want do

end;

FD_WRITE: begin

dspmsg(' 可以发送数据 ');

//do what you want do

end;

FD_ERROR: begin

dspmsg(' 发生错误 ');

// 如果你是客户端 ,则应该是连接不上 ,即端口没有开

end;

FD_CLOSE: Begin

dspmsg(' 服务器断开连接 ');

// 对方关闭连接

end;

FD_CONNECT: begin

dspmsg(' 连结上服务器 ');

// 表示对方端口开放

end;

FD_ACCEPT: begin

dspmsg(' 接收一个请求 ');

// 这个消息只有服务端可能出现

end;

end;

end;

procedure TForm1.FormCreate(Sender: TObject);

var wsaData:TwsaData;

begin // 启动 winsock 动态链接库

if WSAStartup (makeword(2,2), wsaData)0 then begin

messagebox(application.handle,' 无法启动 winsock 动态连接库 !',' 警告 ',MB_OK or MB_APPLMODAL or MB_ICONWARNING);

Application.Terminate;

end;

end;

procedure TForm1.FormDestroy(Sender: TObject);

begin // 关闭 dll

WSACleanup;

end;

procedure TForm1.Button1Click(Sender: TObject);

begin

Sockhd := socket(AF_INET,SOCK_STREAM,0); // 创建 socket 句柄

if Sockhd0 then begin

messagebox(application.handle,' 无法创建句柄 !',' 警告 ',MB_OK or MB_APPLMODAL or MB_ICONWARNING);

exit;

end;

Serv_addr.sin_addr.s_addr:= lookup_hostname(edit1.Text); // 主机名

Serv_addr.sin_family := PF_INET;

Serv_addr.sin_port := htons(23); //any port you want to connect

if WSAAsyncSelect(Sockhd,Form1.handle,WM_SOCKET,FD_ACCEPT or FD_CONNECT or FD_CLOSE or FD_READ or FD_WRITE)=SOCKET_ERROR

then begin

messagebox(application.handle,' 无法创建句柄 !',' 警告 ',MB_OK or MB_APPLMODAL or MB_ICONWARNING);

exit;

end; // 异步 socket

connect(sockhd,serv_addr,sizeof(serv_addr)); // 连接 ,结果会在前面的处理函数处理

end;

end.

相信应该可以满足你的要求

请问如何编程区分这两种情况

更好详细一点喔 ( 我很笨的 )

如果在此地址上无主机存在 ,则发出的数据包得不到回应 ,应用程序会等待超时才

认为连接失败 ( 被 firewall 过滤时情况一样 ),若有主机但被扫描的特定端口不存在时 ,

该主机会发出目的端口不存在的应答

至于如何编程实现 ,应该可以由错误码来判断 ,在 OnError 事情中判定 ErrorCode 是多

小 ,再分别处理 ,ErrorCode 的详情参见 Help

这么高深的问题才 50 分 ,少了

端口扫描不是这么简单 ,否则大家都做

首先你扫描人家的端口会留下自己的痕迹 ,系统有日志可以察看

因此我们做端口扫描的的时候绝对不会直接连接别人 ,而是通过地层的接口编程

例如在 TCP 三次握手的第三次放弃 ,对方就不会有日志 ,这称为 sys 扫描

给对方端口发断开连接的请求称为 fin 扫描 .

通过这两种扫描方式都可以得知对方的端口是否开 ,而且不会留下痕迹 .

总之端口扫描里面有很多学问 ,不是这里可以说清除的

怎么做呀 ,如你所说的话好象要直接调用 socket api?

我现在首先关心的是我提出的问题 ,如何编程区分这两种情况 :

1 。此地址上无任何主机存在

2 。有主机但被扫描的特定端口不存在 ( 也可能是被 firewall 过滤了 )

还有 ,为什么我把 clientsocket 的 onread 里的 errorcode 设为 0 了 ,

还是常常会出现 delphi 自己的错误消息提示 ,象 10061,10057 什么的 ,

这好象是另外一种 error code,如能把它屏蔽我想就不会出现提示了 .

是吗?如果是 ,该怎么做呢。

最后 : 如果能给我一个多线程的端口扫描源码 ,我再给 100 分 ( 真的很穷啊 )

我找到了 help 里的有关说明 ( 是在索引中 Error TCP Event 里找到的 )

WinSock Error Codes

The following error codes apply to the WinSock ActiveX Controls.

Error Code Error Message

10004 The operation is canceled.

10013 The requested address is a broadcast address, but flag is not set.

10014 Invalid argument.

10022 Socket not bound, invalid address or listen is not invoked prior to accept.

10024 No more file descriptors are available, accept queue is empty.

10035 Socket is non-blocking and the specified operation will block.

10036 A blocking Winsock operation is in progress.

10037 The operation is completed. No blocking operation is in progress.

10038 The descriptor is not a socket.

10039 Destination address is required.

10040 The datagram is too large to fit into the buffer and is truncated.

10041 The specified port is the wrong type for this socket.

10042 Option unknown, or unsupported.

10043 The specified port is not supported.

10044 Socket type not supported in this address family.

10045 Socket is not a type that supports connection oriented service.

10047 Address Family is not supported.

10048 Address in use.

10049 Address is not available from the local machine.

10050 Network subsystem failed.

10051 The network cannot be reached from this host at this time.

10052 Connection has timed out when SO_KEEPALIVE is set.

10053 Connection is aborted due to timeout or other failure.

10054 The connection is reset by remote side.

10055 No buffer space is available.

10056 Socket is already connected.

10057 Socket is not connected.

10058 Socket has been shut down.

10060 The attempt to connect timed out.

10061 Connection is forcefully rejected.

10201 Socket already created for this object.

10202 Socket has not been created for this object.

11001 Authoritative answer: Host not found.

11002 Non-Authoritative answer: Host not found.

11003 Non-recoverable errors.

11004 Valid name, no data record of requested type.

我想只要对它进行有关操作就能完全屏蔽 winsocket 错误消息 ( 至少

能屏蔽很多 onerror 里的 errorcode 参数无法屏蔽的消息 )

我终于找到原因所在了

在打开 Socket 时也要捕获异常

try

ClientSocket.Open;

except

MessageBox(MainForm.Handle,'Error connecting to this address','Connect',MB_ICONEXCLAMATION);

end;

在 OnError 中最后要将 ErrorCode 置为 0

if ErrorEvent=eeConnect then

begin

Socket.Close;

MessageBox(MainForm.Handle,'Error connecting to this address','Connect',MB_ICONEXCLAMATION);

end

else if ErrorEvent=eeSend then

Socket.Close;

ErrorCode:=0;

你可能无做之一步

而这样也可以区分你所说的两种情况

1 。第二步 OnError 就是此地址上无任何主机存在 ,到超时就触发 OnError 事件

2 。之一步捕捉到异常就是有主机但被扫描的特定端口不存在

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条大神的评论

发表评论