1.Asynchronous socket error 10061
2.WSAAsyncGetHostByName()çç®ä»
3.c语言ping程序中文注释
Asynchronous socket error 10061
æå¡å¨é误ï¼
端å£æ«æçé®é¢
å¨å端å£æ«ææ¶ ,å¦æä¸æ主æºç¹å®ç«¯å£æ æ³éä¿¡ ,
å°±æ¤ä¸»æºèè¨ ,ææ³åºè¯¥æ以ä¸ä¸¤ç§æ åµ :
1 ãæ¤å°åä¸æ ä»»ä½ä¸»æºåå¨
2 ãæ主æºä½è¢«æ«æçç¹å®ç«¯å£ä¸åå¨ ( ä¹å¯è½æ¯è¢« firewall è¿æ»¤äº )
å¦ä½å¾ç¥æ端å£ä¸æå¼
ç»ä½ æ¥ä¸ªç®åçå§ï¼
procedure TForm1.Timer1Timer(Sender: TObject);
var
I : integer;
begin
Memo1.Clear;
for I := 0 to do begin
ServerSocket1.Close;
ServerSocket1.Port := I;
try
ServerSocket1.Open;
except
Memo1.Lines.Add(IntToStr(I) + ' 端å£è¢«æå¼ !');
end;
end;
end;
对ä¸èµ· ,ææçæ¯å«äººæºå¨ä¸ç PORT
ä½ æ¯è¯´ PORT åªè½è¢«ä¸ä¸ªç¨åºæå¼ä¹ ?
å¯æ¯ ,æç¨ OICQ æ¶å¨æå¼ æ²¡é®é¢å
ææä¸é¢çç¨åºæ¹äºä¸ä¸ ,ä¹å¯ä»¥ç¨çãä½ å°±å»è¯å¾è¿æ¥å¯¹æ¹ ,å¦æéäº ,说ææ¤ç«¯å£è¢«æ
å¼ã
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
--------------------------------------------------------------------------------
æ¥èª :xueminliu æ¶é´ :-3-3 :: ID:
è¦åºå 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.Count> 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 Sockhd<0 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(); //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
è¿ä¹é«æ·±çé®é¢æ å ,å°äº
端å£æ«æä¸æ¯è¿ä¹ç®å ,å¦å大家é½å
é¦å ä½ æ«æ人家ç端å£ä¼çä¸èªå·±çç迹 ,ç³»ç»ææ¥å¿å¯ä»¥å¯ç
å æ¤æ们å端å£æ«æççæ¶åç»å¯¹ä¸ä¼ç´æ¥è¿æ¥å«äºº ,èæ¯éè¿å°å±çæ¥å£ç¼ç¨
ä¾å¦å¨ TCP ä¸æ¬¡æ¡æç第ä¸æ¬¡æ¾å¼ ,对æ¹å°±ä¸ä¼ææ¥å¿ ,è¿ç§°ä¸º sys æ«æ
ç»å¯¹æ¹ç«¯å£åæå¼è¿æ¥ç请æ±ç§°ä¸º fin æ«æ .
éè¿è¿ä¸¤ç§æ«ææ¹å¼é½å¯ä»¥å¾ç¥å¯¹æ¹ç端å£æ¯å¦å¼ ,èä¸ä¸ä¼çä¸ç迹 .
æ»ä¹ç«¯å£æ«æéé¢æå¾å¤å¦é® ,ä¸æ¯è¿éå¯ä»¥è¯´æ¸ é¤ç
æä¹åå ,å¦ä½ æ说çè¯å¥½è±¡è¦ç´æ¥è°ç¨ socket api?
æç°å¨é¦å å ³å¿çæ¯ææåºçé®é¢ ,å¦ä½ç¼ç¨åºåè¿ä¸¤ç§æ åµ :
1 ãæ¤å°åä¸æ ä»»ä½ä¸»æºåå¨
2 ãæ主æºä½è¢«æ«æçç¹å®ç«¯å£ä¸åå¨ ( ä¹å¯è½æ¯è¢« firewall è¿æ»¤äº )
è¿æ ,为ä»ä¹ææ clientsocket ç onread éç errorcode 设为 0 äº ,
è¿æ¯å¸¸å¸¸ä¼åºç° delphi èªå·±çé误æ¶æ¯æ示 ,象 , ä»ä¹ç ,
è¿å¥½è±¡æ¯å¦å¤ä¸ç§ error code,å¦è½æå®å±è½ææ³å°±ä¸ä¼åºç°æç¤ºäº .
æ¯åï¼å¦ææ¯ ,该æä¹åå¢ã
æå : å¦æè½ç»æä¸ä¸ªå¤çº¿ç¨ç端å£æ«ææºç ,æåç» å ( ççå¾ç©·å )
ææ¾å°äº help éçæå ³è¯´æ ( æ¯å¨ç´¢å¼ä¸ Error TCP Event éæ¾å°ç )
WinSock Error Codes
The following error codes apply to the WinSock ActiveX Controls.
Error Code Error Message
The operation is canceled.
The requested address is a broadcast address, but flag is not set.
Invalid argument.
Socket not bound, invalid address or listen is not invoked prior to accept.
No more file descriptors are available, accept queue is empty.
Socket is non-blocking and the specified operation will block.
A blocking Winsock operation is in progress.
The operation is completed. No blocking operation is in progress.
The descriptor is not a socket.
Destination address is required.
The datagram is too large to fit into the buffer and is truncated.
The specified port is the wrong type for this socket.
Option unknown, or unsupported.
The specified port is not supported.
Socket type not supported in this address family.
Socket is not a type that supports connection oriented service.
Address Family is not supported.
Address in use.
Address is not available from the local machine.
Network subsystem failed.
The network cannot be reached from this host at this time.
Connection has timed out when SO_KEEPALIVE is set.
Connection is aborted due to timeout or other failure.
The connection is reset by remote side.
No buffer space is available.
Socket is already connected.
Socket is not connected.
Socket has been shut down.
The attempt to connect timed out.
Connection is forcefully rejected.
Socket already created for this object.
Socket has not been created for this object.
Authoritative answer: Host not found.
Non-Authoritative answer: Host not found.
Non-recoverable errors.
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 ã第ä¸æ¥ææå°å¼å¸¸å°±æ¯æ主æºä½è¢«æ«æçç¹å®ç«¯å£ä¸åå¨
WSAAsyncGetHostByName()çç®ä»
ç®è¿°ï¼è·å¾å¯¹åºäºä¸ä¸ªä¸»æºåç主æºä¿¡æ¯.ï¼å¼æ¥çæ¬.
#include <winsock.h>
HANDLE PASCAL FAR WSAAsyncGetHostByName (HWND hWnd,
unsigned int wMsg,const char FAR * name,char FAR * buf,
int buflen);
hWnd å½å¼æ¥è¯·æ±å®ææ¶ï¼åºè¯¥æ¥æ¶æ¶æ¯ççªå£å¥æ.
wMsg å½å¼æ¥è¯·æ±å®ææ¶ï¼å°è¦æ¥æ¶çæ¶æ¯.
name æå主æºåçæé.
buf æ¥æ¶hostentæ°æ®çæ°æ®åºæé.注æ该æ°æ®åºå¿ 须大äºhostentç»æç大å°.è¿æ¯å 为ä¸ä» Windows Socketså®ç°è¦ç¨è¯¥æ°æ®åºå容纳hostentç»æï¼hostentç»æçæåå¼ç¨çæææ°æ®ä¹è¦å¨è¯¥åºåå .建议ç¨æ·æä¾ä¸ä¸ªMAXGETHOSTSTRUCTåè大å°çç¼å²åº.
buflenä¸è¿°æ°æ®åºç大å°.
注éï¼
æ¬å½æ°æ¯gethostbyname()çå¼æ¥çæ¬ï¼æ¯ç¨æ¥è·å对åºäºä¸ä¸ªä¸»æºåç主æºå称åå°åä¿¡æ¯.Windows Socketsçå®ç°å¯å¨è¯¥æä½åç«å»è¿åè°ç¨æ¹ï¼å¹¶ä¼ åä¸ä¸ªå¼æ¥ä»»å¡å¥æï¼åºç¨ç¨åºå¯ä»¥ç¨å®æ¥æ è¯è¯¥æä½.å½æä½å®ææ¶ï¼ç»æï¼è¥æçè¯ï¼å°ä¼æ·è´å°è°ç¨æ¹æä¾çç¼å²åºï¼åæ¶ååºç¨ç¨åºççªå£åä¸æ¡æ¶æ¯.
å½å¼æ¥æä½å®ææ¶ï¼åºç¨ç¨åºççªå£hWndæ¥æ¶å°æ¶æ¯wMsg. wParamåæ°å å«äºå次å½æ°è°ç¨æ¶è¿åçå¼æ¥ä»»å¡å¥æ.lParamçé«ä½å å«çé误代ç .该代ç å¯ä»¥æ¯winsock.hä¸å®ä¹çä»»ä½é误.é误代ç 为0说æå¼æ¥æä½æå.å¨æåå®æçæ åµä¸ï¼æä¾ç»åå§å½æ°è°ç¨çç¼å²åºä¸å å«äºä¸ä¸ªhostentç»æ.为åå该ç»æä¸çå ç´ ï¼åå§çç¼å²åºæéåºç½®ä¸ºhostentç»æçæéï¼å¹¶ä¸å¦å¹³å¸¸å°åå.
注æè¥é误代ç 为WSAENOBUFSï¼å®è¯´æå¨åå§è°ç¨æ¶ç±buflenæåºçç¼å²åºå¤§å°å¯¹äºå®¹çº³ææçç»æä¿¡æ¯æ¥è¯´å¤ªå°äº.å¨è¿ç§æ åµä¸ï¼lParamçä½ä½å«ææä¾ææä¿¡æ¯æéçç¼å²åºå¤§å°æ°å¼.å¦æåºç¨ç¨åºè®¤ä¸ºè·åçæ°æ®ä¸å¤ï¼å®å°±å¯ä»¥å¨è®¾ç½®äºè¶³å¤å®¹çº³æéä¿¡æ¯çç¼å²åºåï¼éæ°è°ç¨WSAAsyncGetHostByName().ï¼ä¹å°±æ¯å¤§äºlParamä½ä½æä¾ç大å°.)
é误代ç åç¼å²åºå¤§å°åºä½¿ç¨WSAGETASYNCERRORåWSAGETASYNCBUFLENå®ä»lParamä¸ååº.两个å®å®ä¹å¦ä¸ï¼
#define WSAGETASYNCERROR(lParam) HIWORD(lParam)
#define WSAGETASYNCBUFLEN(lParam) LOWORD(lParam)
使ç¨è¿äºå®å¯æ大å°æé«åºç¨ç¨åºæºä»£ç çå¯ç§»æ¤æ§.
è¿åå¼ï¼
è¿åå¼æåºå¼æ¥æä½æ¯å¦æåå°åå¯.注æå®å¹¶ä¸éå«æä½æ¬èº«çæåæ失败.
è¥æä½æåå°åå¯ï¼WSAAsyncGetHostByNameï¼ï¼è¿åä¸ä¸ªHANDLEç±»åçé0å¼ï¼ä½ä¸ºè¯·æ±éè¦çå¼æ¥ä»»å¡å¥æ.该å¼å¯å¨ä¸¤ç§æ¹å¼ä¸ä½¿ç¨.å®å¯éè¿WSACancelAsyncRequest()ç¨æ¥åæ¶è¯¥æä½.ä¹å¯éè¿æ£æ¥wParamæ¶æ¯åæ°ï¼ä»¥å¹é å¼æ¥æä½åå®ææ¶æ¯.
å¦æå¼æ¥æä½ä¸è½åå¯ï¼WSAAsyncGetHostByNameï¼ï¼è¿åä¸ä¸ª0å¼ï¼å¹¶ä¸å¯ä½¿ç¨WSAGetLastErrorï¼ï¼æ¥è·åé误å·.
è¯ä»·ï¼
Windows Socketsçå®ç°ä½¿ç¨æä¾ç»è¯¥å½æ°çç¼å²åºæ¥æé hostentç»æ以å该ç»ææåå¼ç¨çæ°æ®åºå 容.为é¿å ä¸è¿°çWSAENOBUFSé误ï¼åºç¨ç¨åºåºæä¾ä¸ä¸ªè³å°MAXGETHOSTSTRUCTåè大å°çç¼å²åº.
å ³äºWindows Socketsæä¾è ç说æï¼
Windows Socketsçå®ç°åºä¿è¯æ¶æ¯è½æåå°ä¼ ç»åºç¨ç¨åº.å¦æPostMessageï¼ï¼æä½å¤±è´¥ï¼Windows Socketsçå®ç°å¿ é¡»éå该æ¶æ¯ï¼åªè¦çªå£åå¨.
Windows Socketsçæä¾è å¨æ¶æ¯ä¸ç»ç»lParamæ¶åºä½¿ç¨WSAMAKEASYNCREPLYå®.
c语言ping程序中文注释
编写自己的一个ping程序,可以说是许多人迈出网络编程的第一步吧!!这个ping程序的源代码经过我的修改和调试,基本上可以取代windows中自带的ping程序. 各个模块后都有我的详细注释和修改日志,希望能够对大家的学习有所帮助!!
/* 本程序的主要源代码来自MSDN网站, 笔者只是做了一些改进和注释! 另外需要注意的是在Build之前,必须加入ws2_.lib库文件,否则会提示"error LNK:"的错误!*/
Version 1.1 修改记录:
<1> 解决了socket阻塞的企业 源码问题,从而能够正确地处理超时的请求!
<2> 增加了由用户控制发送ICMP包的数目的功能(即命令的第二个参数)
<3> 增加了对ping结果的统计功能.
#pragma pack(4)
#include "winsock2.h"
#include "stdlib.h"
#include "stdio.h"
#define ICMP_ECHO 8
#define ICMP_ECHOREPLY 0
#define ICMP_MIN 8 // minimum 8 byte icmp packet (just header)
/* The IP header */
typedef struct iphdr {
unsigned int h_len:4; // length of the header
unsigned int version:4; // Version of IP
unsigned char tos; // Type of service
unsigned short total_len; // total length of the packet
unsigned short ident; // unique identifier
unsigned short frag_and_flags; // flags
unsigned char ttl;
unsigned char proto; // protocol (TCP, UDP etc)
unsigned short checksum; // IP checksum
unsigned int sourceIP;
unsigned int destIP;
}IpHeader;
//
// ICMP header
//
typedef struct icmphdr {
BYTE i_type;
BYTE i_code; /* type sub code */
USHORT i_cksum;
USHORT i_id;
USHORT i_seq;
/* This is not the std header, but we reserve space for time */
ULONG timestamp;
}IcmpHeader;
#define STATUS_FAILED 0xFFFF
#define DEF_PACKET_SIZE
#define DEF_PACKET_NUMBER 4 /* 发送数据报的个数 */
#define MAX_PACKET
#define xmalloc(s) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(s))
#define xfree(p) HeapFree (GetProcessHeap(),0,(p))
void fill_icmp_data(char *, int);
USHORT checksum(USHORT *, int);
int decode_resp(char *,int ,struct sockaddr_in *);
void Usage(char *progname){
fprintf(stderr,"Usage:\n");
fprintf(stderr,"%s [number of packets] [data_size]\n",progname);
fprintf(stderr,"datasize can be up to 1Kb\n");
ExitProcess(STATUS_FAILED);
}
int main(int argc, char **argv){
WSADATA wsaData;
SOCKET sockRaw;
struct sockaddr_in dest,from;
struct hostent * hp;
int bread,datasize,times;
int fromlen = sizeof(from);
int timeout = ;
int statistic = 0; /* 用于统计结果 */
char *dest_ip;
char *icmp_data;
char *recvbuf;
unsigned int addr=0;
USHORT seq_no = 0;
if (WSAStartup(MAKEWORD(2,1),&wsaData) != 0){
fprintf(stderr,"WSAStartup failed: %d\n",GetLastError());
ExitProcess(STATUS_FAILED);
}
if (argc <2 ) {
Usage(argv[0]);
}
sockRaw = WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL, 0,WSA_FLAG_OVERLAPPED);
//
//注:为了使用发送接收超时设置(即设置SO_RCVTIMEO, SO_SNDTIMEO),
// 必须将标志位设为WSA_FLAG_OVERLAPPED !
//
if (sockRaw == INVALID_SOCKET) {
fprintf(stderr,mjextension 源码解析"WSASocket() failed: %d\n",WSAGetLastError());
ExitProcess(STATUS_FAILED);
}
bread = setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,
sizeof(timeout));
if(bread == SOCKET_ERROR) {
fprintf(stderr,"failed to set recv timeout: %d\n",WSAGetLastError());
ExitProcess(STATUS_FAILED);
}
timeout = ;
bread = setsockopt(sockRaw,SOL_SOCKET,SO_SNDTIMEO,(char*)&timeout,
sizeof(timeout));
if(bread == SOCKET_ERROR) {
fprintf(stderr,"failed to set send timeout: %d\n",WSAGetLastError());
ExitProcess(STATUS_FAILED);
}
memset(&dest,0,sizeof(dest));
hp = gethostbyname(argv[1]);
if (!hp){
addr = inet_addr(argv[1]);
}
if ((!hp) && (addr == INADDR_NONE) ) {
fprintf(stderr,"Unable to resolve %s\n",argv[1]);
ExitProcess(STATUS_FAILED);
}
if (hp != NULL)
memcpy(&(dest.sin_addr),hp->h_addr,hp->h_length);
else
dest.sin_addr.s_addr = addr;
if (hp)
dest.sin_family = hp->h_addrtype;
else
dest.sin_family = AF_INET;
dest_ip = inet_ntoa(dest.sin_addr);
//
// atoi函数原型是: int atoi( const char *string );
// The return value is 0 if the input cannot be converted to an integer !
//
if(argc>2)
{
times=atoi(argv[2]);
if(times == 0)
times=DEF_PACKET_NUMBER;
}
else
times=DEF_PACKET_NUMBER;
if (argc >3)
{
datasize = atoi(argv[3]);
if (datasize == 0)
datasize = DEF_PACKET_SIZE;
if (datasize >) /* 用户给出的数据包大小太大 */
{
fprintf(stderr,"WARNING : data_size is too large !\n");
datasize = DEF_PACKET_SIZE;
}
}
else
datasize = DEF_PACKET_SIZE;
datasize += sizeof(IcmpHeader);
icmp_data = (char*)xmalloc(MAX_PACKET);
recvbuf = (char*)xmalloc(MAX_PACKET);
if (!icmp_data) {
fprintf(stderr,"HeapAlloc failed %d\n",GetLastError());
ExitProcess(STATUS_FAILED);
}
memset(icmp_data,0,MAX_PACKET);
fill_icmp_data(icmp_data,datasize);
//
//显示提示信息
//
fprintf(stdout,"\nPinging %s ....\n\n",dest_ip);
for(int i=0;i{
int bwrote;
((IcmpHeader*)icmp_data)->i_cksum = 0;
((IcmpHeader*)icmp_data)->timestamp = GetTickCount();
((IcmpHeader*)icmp_data)->i_seq = seq_no++;
((IcmpHeader*)icmp_data)->i_cksum = checksum((USHORT*)icmp_data,datasize);
bwrote = sendto(sockRaw,icmp_data,datasize,0,(struct sockaddr*)&dest,sizeof(dest));
if (bwrote == SOCKET_ERROR){
if (WSAGetLastError() == WSAETIMEDOUT) {
printf("Request timed out.\n");
continue;
}
fprintf(stderr,"sendto failed: %d\n",WSAGetLastError());
ExitProcess(STATUS_FAILED);
}
if (bwrote < datasize ) {
fprintf(stdout,"Wrote %d bytes\n",bwrote);
}
bread = recvfrom(sockRaw,recvbuf,MAX_PACKET,0,(struct sockaddr*)&from,&fromlen);
if (bread == SOCKET_ERROR){
if (WSAGetLastError() == WSAETIMEDOUT) {
printf("Request timed out.\n");
continue;
}
fprintf(stderr,"recvfrom failed: %d\n",WSAGetLastError());
ExitProcess(STATUS_FAILED);
}
if(!decode_resp(recvbuf,bread,&from))
statistic++; /* 成功接收的数目++ */
Sleep();
}
/
*Display the statistic result
*/
fprintf(stdout,"\nPing statistics for %s \n",dest_ip);
fprintf(stdout," Packets: Sent = %d,Received = %d, Lost = %d (%2.0f%% loss)\n",times,
statistic,(times-statistic),(float)(times-statistic)/times*);
WSACleanup();
return 0;
}
/*
The response is an IP packet. We must decode the IP header to locate
the ICMP data
*/
int decode_resp(char *buf, int bytes,struct sockaddr_in *from) {
IpHeader *iphdr;
IcmpHeader *icmphdr;
unsigned short iphdrlen;
iphdr = (IpHeader *)buf;
iphdrlen = (iphdr->h_len) * 4 ; // number of -bit words *4 = bytes
if (bytes < iphdrlen + ICMP_MIN) {
printf("Too few bytes from %s\n",inet_ntoa(from->sin_addr));
}
icmphdr = (IcmpHeader*)(buf + iphdrlen);
if (icmphdr->i_type != ICMP_ECHOREPLY) {
fprintf(stderr,"non-echo type %d recvd\n",icmphdr->i_type);
return 1;
}
if (icmphdr->i_id != (USHORT)GetCurrentProcessId()) {
fprintf(stderr,"someone else''s packet!\n");
return 1;
}
printf("%d bytes from %s:",bytes, inet_ntoa(from->sin_addr));
printf(" icmp_seq = %d. ",icmphdr->i_seq);
printf(" time: %d ms ",GetTickCount()-icmphdr->timestamp);
printf("\n");
return 0;
}
USHORT checksum(USHORT *buffer, int size) {
unsigned long cksum=0;
while(size >1) {
cksum+=*buffer++;
size -=sizeof(USHORT);
}
if(size) {
cksum += *(UCHAR*)buffer;
}
cksum = (cksum >> ) + (cksum & 0xffff);
cksum += (cksum >>);
return (USHORT)(~cksum);
}
/*
Helper function to fill in various stuff in our ICMP request.
*/
void fill_icmp_data(char * icmp_data, int datasize){
IcmpHeader *icmp_hdr;
char *datapart;
icmp_hdr = (IcmpHeader*)icmp_data;
icmp_hdr->i_type = ICMP_ECHO;
icmp_hdr->i_code = 0;
icmp_hdr->i_id = (USHORT)GetCurrentProcessId();
icmp_hdr->i_cksum = 0;
icmp_hdr->i_seq = 0;
datapart = icmp_data + sizeof(IcmpHeader);
//
// Place some junk in the buffer.
//
memset(datapart,''E'', datasize - sizeof(IcmpHeader));
}
/