实验一:基于Winsock完成简单的网络程序开发
第一部分:简答的UDP网络通信程序
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 // UDP5555.cpp : Defines the entry point for the application. 2 //========================================================================= 3 //陈家琪,计算机网络课程,传输层与应用层协议-用户数据报协议UDP 4 //说明:在窗口里点击鼠标左键,则发送信息到远程机。 5 //========================================================================= 6 //VC 6.0 add WSOCK32.LIB in Project -> Settings... -> Link 7 #include <winsock.h> 8 //-------------------------------------------------------------- 9 // Global Variables: 10 HINSTANCE hInst; // 实例句柄,方便各程序访问 11 HWND hWnd; // 主窗口句柄,方便各程序访问 12 char Title[]="UDP[5555]"; // 窗口标题 The title bar text 13 int WinX0=200,WinY0=100,WinW=200,WinH=500; // 窗口位置、大小 14 15 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 16 //-------------------------------------------------------------- 17 int APIENTRY WinMain(HINSTANCE hI,HINSTANCE hP,LPSTR lp,int nC) 18 { 19 MSG msg; 20 hInst = hI; // Store instance handle in our global variable 21 WNDCLASS wc; 22 23 memset(&wc,0,sizeof(WNDCLASS)); 24 25 wc.lpfnWndProc = (WNDPROC)WndProc; 26 wc.hInstance = hI; 27 wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); 28 wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1); 29 wc.lpszClassName = "Win32API"; 30 RegisterClass(&wc); 31 //特殊窗口1,始终在顶层,任务栏显示。 32 hWnd=CreateWindowEx(WS_EX_TOPMOST,"Win32API",Title, 33 WS_DLGFRAME|WS_SYSMENU, 34 WinX0,WinY0,WinW,WinH, // 窗口位置、大小 35 NULL, NULL, hI, NULL); 36 37 if (!hWnd) return FALSE; 38 39 ShowWindow(hWnd, nC); 40 // Main message loop: 41 while (GetMessage(&msg, NULL, 0, 0)) 42 { 43 TranslateMessage(&msg); 44 DispatchMessage(&msg); 45 } 46 return msg.wParam; 47 } 48 //-------------------------------------------------------------- 49 WSADATA ws; 50 SOCKET Cs1,Cs2; 51 struct sockaddr_in Cs1A,Cs2A; 52 char aa[200]; 53 char bb[200]; 54 int d; 55 #define Cs1Port 5555 //本地端口 56 #define Cs2Port 6666 //远程端口 57 #define Cs1IP "127.0.0.1" //本地网址 58 #define Cs2IP "127.0.0.1" //远程网址 59 //-------------------------------------------------------------- 60 //消息处理 61 LRESULT CALLBACK WndProc(HWND hW, UINT msg, WPARAM wP, LPARAM lP) 62 { 63 switch (msg) 64 { 65 case WM_DESTROY: //关闭程序触发事件 66 WSAAsyncSelect(Cs1, hW, 0, 0); //向Windows注销Socket触发事件 67 closesocket(Cs1); //释放连接 68 WSACleanup( ); //卸载动态连接库WinSock DLL 69 PostQuitMessage(0); 70 break; 71 case WM_CREATE: //程序初始化触发事件 72 WSAStartup(0x0101,&ws); //装载动态连接库WinSock DLL 73 Cs1=socket(AF_INET, SOCK_DGRAM,0); //创建UDP套接字Socket 74 Cs1A.sin_family=AF_INET; //地址类型:AF_INET for Internet 75 Cs1A.sin_port = htons(Cs1Port); //本地Socket的属性:端口 76 Cs1A.sin_addr.s_addr =inet_addr(Cs1IP); //本地Socket的属性:IP地址 77 d=bind(Cs1,(struct sockaddr *) &Cs1A,sizeof(Cs1A)); //设置本地socket的属性,捆绑 78 Cs2A.sin_family=AF_INET; //地址类型:AF_INET for Internet 79 Cs2A.sin_port = htons(Cs2Port); //远程Socket的属性:端口 80 Cs2A.sin_addr.s_addr =inet_addr(Cs2IP); //远程Socket的属性:IP地址 81 WSAAsyncSelect(Cs1,hW,WM_USER+1,FD_READ); //向Windows注册Socket触发事件 82 Beep(2000,100); 83 break; 84 case WM_USER+1: //Socket触发事件 85 switch(LOWORD(lP)) 86 { 87 case FD_READ: //收到远程信息 88 // d=recvfrom(Cs1,bb,sizeof(bb),0,(struct sockaddr *) &Cs2A,&d); 89 d=recv(wP,bb,sizeof(bb),0);//wP=Cs //读接收缓冲区 90 bb[d]=0; 91 MessageBox(0,bb,"UDP[5555](FD_READ)",0); 92 break; 93 } 94 break; 95 case WM_LBUTTONDOWN: //点击鼠标左键 96 wsprintf(aa,"UDP[5555]:Hello!"); 97 d = sizeof(Cs2A); 98 sendto(Cs1,aa,strlen(aa),0,(struct sockaddr *) &Cs2A,d); //发送信息"UDP[5555]:Hello!" 99 break; 100 } 101 return DefWindowProc(hW,msg,wP,lP); 102 } 103 //--------------------------------------------------------------
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 // UDP6666.cpp : Defines the entry point for the application. 2 //========================================================================= 3 //用户数据报协议UDP 4 //说明:在窗口里点击鼠标左键,则发送信息到远程机。 5 //========================================================================= 6 //VC 6.0 add WSOCK32.LIB in Project -> Settings... -> Link 7 #include <winsock.h> 8 //-------------------------------------------------------------- 9 // Global Variables: 10 HINSTANCE hInst; // 实例句柄,方便各程序访问 11 HWND hWnd; // 主窗口句柄,方便各程序访问 12 char Title[]="UDP[6666]"; // 窗口标题 The title bar text 13 int WinX0=500,WinY0=100,WinW=200,WinH=500; // 窗口位置、大小 14 15 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 16 //-------------------------------------------------------------- 17 int APIENTRY WinMain(HINSTANCE hI,HINSTANCE hP,LPSTR lp,int nC) 18 { 19 MSG msg; 20 hInst = hI; // Store instance handle in our global variable 21 WNDCLASS wc; 22 23 memset(&wc,0,sizeof(WNDCLASS)); 24 25 wc.lpfnWndProc = (WNDPROC)WndProc; 26 wc.hInstance = hI; 27 wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); 28 wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1); 29 wc.lpszClassName = "Win32API"; 30 RegisterClass(&wc); 31 //特殊窗口1,始终在顶层,任务栏显示。 32 hWnd=CreateWindowEx(WS_EX_TOPMOST,"Win32API",Title, 33 WS_DLGFRAME|WS_SYSMENU, 34 WinX0,WinY0,WinW,WinH, // 窗口位置、大小 35 NULL, NULL, hI, NULL); 36 37 if (!hWnd) return FALSE; 38 39 ShowWindow(hWnd, nC); 40 // Main message loop: 41 while (GetMessage(&msg, NULL, 0, 0)) 42 { 43 TranslateMessage(&msg); 44 DispatchMessage(&msg); 45 } 46 return msg.wParam; 47 } 48 //-------------------------------------------------------------- 49 WSADATA ws; 50 SOCKET Cs1,Cs2; 51 struct sockaddr_in Cs1A,Cs2A; 52 char aa[200]; 53 char bb[200]; 54 int d; 55 #define Cs1Port 6666 //本地端口 56 #define Cs2Port 5555 //远程端口 57 #define Cs1IP "127.0.0.1" //本地网址 58 #define Cs2IP "127.0.0.1" //远程网址 59 //-------------------------------------------------------------- 60 //消息处理 61 LRESULT CALLBACK WndProc(HWND hW, UINT msg, WPARAM wP, LPARAM lP) 62 { 63 switch (msg) 64 { 65 case WM_DESTROY: //关闭程序触发事件 66 WSAAsyncSelect(Cs1, hW, 0, 0); //向Windows注销Socket触发事件 67 closesocket(Cs1); //释放连接 68 WSACleanup( ); //卸载动态连接库WinSock DLL 69 PostQuitMessage(0); 70 break; 71 case WM_CREATE: //程序初始化触发事件 72 WSAStartup(0x0101,&ws); //装载动态连接库WinSock DLL 73 Cs1=socket(AF_INET, SOCK_DGRAM,0); //创建UDP套接字Socket 74 Cs1A.sin_family=AF_INET; //地址类型:AF_INET for Internet 75 Cs1A.sin_port = htons(Cs1Port); //本地Socket的属性:端口 76 Cs1A.sin_addr.s_addr =inet_addr(Cs1IP); //本地Socket的属性:IP地址 77 d=bind(Cs1,(struct sockaddr *) &Cs1A,sizeof(Cs1A)); //设置本地socket的属性,捆绑 78 Cs2A.sin_family=AF_INET; //地址类型:AF_INET for Internet 79 Cs2A.sin_port = htons(Cs2Port); //远程Socket的属性:端口 80 Cs2A.sin_addr.s_addr =inet_addr(Cs2IP); //远程Socket的属性:IP地址 81 WSAAsyncSelect(Cs1,hW,WM_USER+1,FD_READ); //向Windows注册Socket触发事件 82 Beep(2000,100); 83 break; 84 case WM_USER+1: //Socket触发事件 85 switch(LOWORD(lP)) 86 { 87 case FD_READ: //收到远程信息 88 // d=recvfrom(Cs1,bb,sizeof(bb),0,(struct sockaddr *) &Cs2A,&d); 89 d=recv(wP,bb,sizeof(bb),0);//wP=Cs //读接收缓冲区 90 bb[d]=0; 91 MessageBox(0,bb,"UDP[6666](FD_READ)",0); 92 break; 93 } 94 break; 95 case WM_LBUTTONDOWN: //点击鼠标左键 96 wsprintf(aa,"UDP[6666]:Hello!"); 97 d = sizeof(Cs2A); 98 sendto(Cs1,aa,strlen(aa),0,(struct sockaddr *) &Cs2A,d); //发送信息"UDP[6666]:Hello!" 99 break; 100 } 101 return DefWindowProc(hW,msg,wP,lP); 102 } 103 //--------------------------------------------------------------
第二部分:简单的TCP网络通信程序
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //Server.cpp : Defines the entry point for the application. use VC 6.0 2 //========================================================================= 3 //说明:监听客户机连接请求, 向客户机发送连接应答"Server:Welcome!"; 4 //说明:接收客户机服务请求, 向客户机发送服务数据. 5 //========================================================================= 6 //VC6.0 add WSOCK32.LIB in Project->Settings...->Link 7 #include <winsock.h> //by user 8 //------------------------------------------------ 9 // Global Variables: 10 HINSTANCE hInst; // 实例句柄,方便各程序访问 11 HWND hWnd; // 主窗口句柄,方便各程序访问 12 char Title[]=" TCP-Server "; // 窗口标题 The title bar text 13 int WinX0=500,WinY0=100,WinW=300,WinH=50; // 窗口位置、大小 14 15 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 16 //------------------------------------------------ 17 int APIENTRY WinMain(HINSTANCE hI,HINSTANCE hP,LPSTR lp,int nC) 18 { 19 MSG msg; 20 hInst = hI; // Store instance handle in our global variable 21 WNDCLASS wc; 22 23 memset(&wc,0,sizeof(WNDCLASS)); 24 25 wc.lpfnWndProc = (WNDPROC)WndProc; 26 wc.hInstance = hI; 27 wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); 28 wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1); 29 wc.lpszClassName = "Win32API"; 30 RegisterClass(&wc); 31 //特殊窗口1,始终在顶层,任务栏显示。 32 hWnd=CreateWindowEx(WS_EX_TOPMOST,"Win32API",Title, 33 WS_DLGFRAME|WS_SYSMENU, 34 WinX0,WinY0,WinW,WinH, // 窗口位置、大小 35 NULL, NULL, hI, NULL); 36 if(!hWnd) return FALSE; 37 38 ShowWindow(hWnd, nC); 39 // Main message loop: 40 while (GetMessage(&msg, NULL, 0, 0)) 41 { 42 TranslateMessage(&msg); 43 DispatchMessage(&msg); 44 } 45 return msg.wParam; 46 } 47 //------------------------------------------------ 48 WSADATA ws; 49 SOCKET Ss,Cs; //服务器和客户机的套接口变量 50 struct sockaddr_in SA,CA; //服务器和客户机的主机地址变量 51 WORD SPort = 6666; //本机端口(服务器) 52 //char SIP[16]="127.0.0.1"; //本机IP地址(服务器) 53 char SIP[16]="0.0.0.0"; //本机IP地址(服务器) 54 char Msg[666],Buf[666]; 55 int d,l=sizeof(CA); 56 //------------------------------------------------ 57 void SetSockAddr(struct sockaddr_in *A,WORD Port,char *IP) 58 { 59 A->sin_family = AF_INET; //TCP/IP协议 60 A->sin_port = htons(Port); //端口。 61 A->sin_addr.s_addr =inet_addr(IP); //IP网址。 62 } 63 //------------------------------------------------ 64 //消息处理 65 LRESULT CALLBACK WndProc(HWND hW,UINT msg, 66 WPARAM wP,LPARAM lP) 67 { 68 switch (msg) 69 { 70 case WM_CREATE: //消息:产生窗口 71 WSAStartup(0x0101,&ws); 72 Ss=socket(AF_INET, SOCK_STREAM,0); //创建套接口(流式) 73 SetSockAddr(&SA,SPort,SIP); //设置服务器主机地址 74 d=bind(Ss,(struct sockaddr *)&SA,sizeof(SA));//捆绑主机地址 75 if(d!=0) 76 { 77 wsprintf(Msg,"[Server] %s","bind Error!"); 78 SetWindowText(hW, Msg); //在窗口标题栏显示连接信息 79 break; 80 } 81 //向windows注册套接口Ss所产生的网络消息事件。 82 WSAAsyncSelect(Ss,hW,WM_USER+1,FD_ACCEPT|FD_READ|FD_CLOSE); 83 listen(Ss,5); //监听客户机连接请求 84 break; 85 case WM_DESTROY: //消息:关闭窗口 86 WSAAsyncSelect(Ss, hW, 0, 0); //注销套接口Ss的消息事件。 87 closesocket(Ss); //关闭套接口Ss 88 WSACleanup(); //卸载WinSock DLL 89 PostQuitMessage(0); //向windows发送退出程序的消息 90 break; 91 case WM_USER+1: 92 switch(LOWORD(lP)) 93 { 94 case FD_ACCEPT: 95 Cs=accept(Ss,(struct sockaddr *)&CA,&l);//获取客户机主机地址 96 wsprintf(Msg,"[Server]Client[%d] come in!",Cs); 97 SetWindowText(hW, Msg); //在窗口标题栏显示连接信息 98 99 wsprintf(Msg,"Server:Welcome!"); 100 send(Cs, Msg,strlen(Msg),0); //向客户机发送连接应答 101 break; 102 case FD_READ: 103 d=recv(wP,Buf,sizeof(Buf),0); //接收客户机服务请求,wP=Cs 104 Buf[d]=0; 105 wsprintf(Msg,"[Server]Client[%d]:%s",wP,Buf); 106 SetWindowText(hW, Msg); //在窗口标题栏显示服务请求 107 108 wsprintf(Msg,"Server:%s",Buf); 109 send(wP, Msg,strlen(Msg),0); //向客户机发送服务数据 110 break; 111 case FD_CLOSE: 112 wsprintf(Msg,"[Server]Client[%d] leave!",wP); 113 SetWindowText(hW, Msg); //在窗口标题栏显示信息 114 break; 115 } 116 break; 117 } 118 return DefWindowProc(hW,msg,wP,lP); 119 } 120 //------------------------------------------------
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //Client.cpp : Defines the entry point for the application. use VC 6.0 2 //========================================================================= 3 //基于TCP,Client程序 4 //说明:鼠标左键按下: 向服务器发送服务请求"Hello!" 5 //说明:鼠标右键按下: 向服务器发送服务请求"Hi!" 6 //========================================================================= 7 //VC6.0 add WSOCK32.LIB in Project->Settings...->Link 8 #include <winsock.h> //by user 9 //------------------------------------------------ 10 // Global Variables: 11 HINSTANCE hInst; // 实例句柄,方便各程序访问 12 HWND hWnd; // 主窗口句柄,方便各程序访问 13 char Title[]=" TCP-Client "; // 窗口标题 The title bar text 14 int WinX0=310,WinY0=10,WinW=300,WinH=50; // 窗口位置、大小 15 16 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 17 //------------------------------------------------ 18 int APIENTRY WinMain(HINSTANCE hI,HINSTANCE hP,LPSTR lp,int nC) 19 { 20 MSG msg; 21 hInst = hI; // Store instance handle in our global variable 22 WNDCLASS wc; 23 24 memset(&wc,0,sizeof(WNDCLASS)); 25 26 wc.lpfnWndProc = (WNDPROC)WndProc; 27 wc.hInstance = hI; 28 wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); 29 wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1); 30 wc.lpszClassName = "Win32API"; 31 RegisterClass(&wc); 32 //特殊窗口1,始终在顶层,任务栏显示。 33 hWnd=CreateWindowEx(WS_EX_TOPMOST,"Win32API",Title, 34 WS_DLGFRAME|WS_SYSMENU, 35 // WinX0,WinY0,WinW,WinH, // 窗口位置、大小 36 CW_USEDEFAULT,CW_USEDEFAULT,WinW,WinH, // 窗口位置 Windows selects the default position 、大小 37 NULL, NULL, hI, NULL); 38 if(!hWnd) return FALSE; 39 40 ShowWindow(hWnd, nC); 41 // Main message loop: 42 while (GetMessage(&msg, NULL, 0, 0)) 43 { 44 TranslateMessage(&msg); 45 DispatchMessage(&msg); 46 } 47 return msg.wParam; 48 } 49 //------------------------------------------------ 50 WSADATA ws; 51 SOCKET Ss,Cs; //服务器和客户机的套接口变量 52 struct sockaddr_in SA,CA; //服务器和客户机的主机地址变量 53 WORD SPort = 6666; //远程服务器端口 54 char SIP[16]="127.0.0.1"; //远程服务器IP地址 55 //char SIP[16]="0.0.0.0"; //远程服务器IP地址 56 char Msg[666],Buf[666]; 57 int d,l=sizeof(CA); 58 //------------------------------------------------ 59 void SetSockAddr(struct sockaddr_in *A,WORD Port,char *IP) 60 { 61 A->sin_family = AF_INET; //TCP/IP协议 62 A->sin_port = htons(Port); //端口。 63 A->sin_addr.s_addr =inet_addr(IP); //IP网址。 64 } 65 //------------------------------------------------ 66 //消息处理 67 LRESULT CALLBACK WndProc(HWND hW,UINT msg,WPARAM wP,LPARAM lP) 68 { 69 switch (msg) 70 { 71 case WM_CREATE: 72 WSAStartup(0x0101,&ws); 73 Cs=socket(AF_INET,SOCK_STREAM,0); //创建套接口(流式) 74 SetSockAddr(&SA,SPort,SIP); //服务器主机地址(远程) 75 WSAAsyncSelect(Cs,hW,WM_USER+1,FD_READ|FD_CLOSE); 76 d=connect(Cs,(struct sockaddr *)&SA, sizeof(SA));//连接服务器 77 if(d!=0) 78 { 79 wsprintf(Msg,"[Client]%s","connect Error!"); 80 SetWindowText(hW, Msg); //在窗口标题栏显示服务数据 81 break; 82 } 83 84 break; 85 case WM_DESTROY: //消息:关闭窗口 86 WSAAsyncSelect(Cs, hW, 0, 0); //注销套接口Cs的消息事件。 87 closesocket(Cs); //关闭套接口Cs 88 WSACleanup(); //卸载WinSock DLL 89 PostQuitMessage(0); //向windows发送退出程序的消息 90 break; 91 case WM_USER+1: 92 switch(LOWORD(lP)) 93 { 94 case FD_READ: 95 d=recv(wP,Buf,sizeof(Buf),0); //接收服务器的服务数据,wP=Cs 96 Buf[d]=0; 97 wsprintf(Msg,"[Client]%s",Buf); 98 SetWindowText(hW, Msg); //在窗口标题栏显示服务数据 99 break; 100 case FD_CLOSE: 101 wsprintf(Msg,"[Client]Server Stop! [%d]",wP); 102 SetWindowText(hW, Msg); //在窗口标题栏显示信息 103 break; 104 } 105 break; 106 case WM_LBUTTONDOWN: //消息:鼠标左键按下 107 wsprintf(Msg,"Hello!"); 108 send(Cs, Msg,strlen(Msg),0); //向服务器发送服务请求"Hello!" 109 break; 110 case WM_RBUTTONDOWN: //消息:鼠标右键按下 111 wsprintf(Msg,"Hi!"); 112 send(Cs, Msg,strlen(Msg),0); //向服务器发送服务请求"Hi!" 113 break; 114 } 115 return DefWindowProc(hW,msg,wP,lP); 116 } 117 //------------------------------------------------
第三部分:简单的CHAR聊天室网络应用程序
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //ChatSer.cpp : Defines the entry point for the application. use VC 6.0 2 //========================================================================= 3 //传输层协议-传输控制协议TCP 4 //说明: Chat Server服务器端程序 5 //========================================================================= 6 //VC 6.0 add WSOCK32.LIB in Project -> Settings... -> Link 7 #include <winsock.h> 8 #include <stdlib.h> 9 //-------------------------------------------------------------- 10 // Global Variables: 11 HINSTANCE hInst; // 实例句柄,方便各程序访问 12 HWND hWnd; // 主窗口句柄,方便各程序访问 13 char Title[]="Chat-Server"; // 窗口标题 The title bar text 14 int WinX0=500,WinY0=100,WinW=360,WinH=200; // 窗口位置、大小 15 16 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 17 //-------------------------------------------------------------- 18 int APIENTRY WinMain(HINSTANCE hI,HINSTANCE hP,LPSTR lp,int nC) 19 { 20 MSG msg; 21 hInst = hI; // Store instance handle in our global variable 22 WNDCLASS wc; 23 24 memset(&wc,0,sizeof(WNDCLASS)); 25 26 wc.lpfnWndProc = (WNDPROC)WndProc; 27 wc.hInstance = hI; 28 wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); 29 wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1); 30 wc.lpszClassName = "Win32API"; 31 RegisterClass(&wc); 32 //特殊窗口1,始终在顶层,任务栏显示。 33 hWnd=CreateWindowEx(WS_EX_TOPMOST,"Win32API",Title, 34 WS_DLGFRAME|WS_SYSMENU, 35 WinX0,WinY0,WinW,WinH, // 窗口位置、大小 36 NULL, NULL, hI, NULL); 37 if(!hWnd) return FALSE; 38 39 ShowWindow(hWnd, nC); 40 // Main message loop: 41 while (GetMessage(&msg, NULL, 0, 0)) 42 { 43 TranslateMessage(&msg); 44 DispatchMessage(&msg); 45 } 46 return msg.wParam; 47 } 48 //-------------------------------------------------------------- 49 //按钮 50 HWND CreateButton(char *Titel,int x0,int y0,int w,int h,int ID,HWND hW,HINSTANCE hInst) 51 { 52 return CreateWindowEx(WS_EX_PALETTEWINDOW,"BUTTON",Titel, 53 WS_VISIBLE | WS_CHILD , 54 x0,y0,w,h, hW,(HMENU)ID,hInst,NULL); 55 } 56 //--------------------------------------------------------------------------- 57 //单行编辑框 58 HWND CreateEdit(char *Titel,int x0,int y0,int w,int h,int ID,HWND hW,HINSTANCE hInst) 59 { 60 return CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT",Titel, 61 WS_VISIBLE | WS_CHILD | 62 ES_LEFT | ES_MULTILINE | WS_HSCROLL , 63 x0,y0,w,h, hW, 64 (HMENU)ID,hInst,NULL); 65 } 66 //--------------------------------------------------------------------------- 67 //多行文本框 68 HWND CreateMemo(char *Titel,int x0,int y0,int w,int h,int ID,HWND hW,HINSTANCE hInst) 69 { 70 return CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT",Titel, 71 WS_VISIBLE | WS_CHILD | 72 ES_LEFT | ES_MULTILINE |ES_READONLY| 73 WS_HSCROLL | WS_VSCROLL, 74 x0,y0,w,h, 75 hW,(HMENU)ID,hInst,NULL); 76 } 77 //--------------------------------------------------------------------------- 78 //向多行文本框中添加文本 79 void Puts(HWND hW,int ID_EDIT,char *str) 80 { 81 int nLen=GetWindowTextLength(GetDlgItem(hW,ID_EDIT)); 82 SendMessage(GetDlgItem(hW,ID_EDIT),EM_SETSEL,nLen,nLen); 83 SendMessage(GetDlgItem(hW,ID_EDIT),EM_REPLACESEL,TRUE,(long)(LPCTSTR)str); 84 nLen=GetWindowTextLength(GetDlgItem(hW,ID_EDIT)); 85 SendMessage(GetDlgItem(hW,ID_EDIT),EM_SETSEL,nLen,nLen); 86 SendMessage(GetDlgItem(hW,ID_EDIT),EM_REPLACESEL,TRUE,(long)(LPCTSTR)"\r\n"); 87 } 88 //--------------------------------------------------------------------------- 89 //按钮 90 #define BUTTON1 501 91 #define BUTTON2 502 92 //--------------------------------------------------------------------------- 93 //单行编辑框 94 #define EDIT1 601 95 #define EDIT2 602 96 #define EDIT3 603 97 //--------------------------------------------------------------------------- 98 //多行编辑框 99 #define MEMO1 701 100 //--------------------------------------------------------------------------- 101 #define UN 100 //100个用户登录信息 102 WSADATA ws; 103 SOCKET Ss,Cs,Csi[UN]; 104 struct sockaddr_in SA,CA,CAi[11]; 105 char aa[200]; 106 char bb[200]; 107 char User[UN][20]; 108 int d; 109 int GetUserBySocket(SOCKET s) 110 { 111 int i; 112 for(i=0;i<UN;i++) 113 if(Csi[i]==s) 114 break; 115 return i; 116 } 117 void Broadcast(SOCKET s,char *str) 118 { 119 char a1[200]; 120 int i; 121 int ui; 122 ui = GetUserBySocket(s); 123 for(i=0;i<UN;i++) 124 { 125 if(Csi[i]==-1) continue; 126 wsprintf(a1,"%s:%s",User[ui],str); 127 send(Csi[i],a1,strlen(a1),0); 128 } 129 } 130 int NameCmp(char *str) 131 { 132 int i; 133 for(i=0;i<UN;i++) 134 if(!strcmp(User[i],str)) return 1; 135 return 0; 136 } 137 void BroadcastToClients(HWND hW,SOCKET s,char *str) //向其它客户转发信息或用户登录名注册 138 { 139 int i,j=1; 140 for(i=0;i<UN;i++) 141 if((Csi[i]==s) && (User[i][0]==0)) 142 { 143 strcpy(aa,str); 144 while(NameCmp(aa)) //查找用户登录名 145 wsprintf(aa,"%s-%d",str,j++); 146 if(j>1) 147 { 148 wsprintf(bb,"Your Name=%s!",aa); 149 send(s,bb,strlen(bb),0); 150 } 151 strcpy(User[i],aa); 152 wsprintf(aa,"Come in!"); 153 Broadcast(s,aa); //广播“新用户 Come in!” 154 wsprintf(aa,"%s:Come in![%s:%d]",User[i], 155 inet_ntoa(CAi[i].sin_addr),ntohs(CAi[i].sin_port)); 156 Puts(hW,MEMO1,aa); 157 return; 158 } 159 Broadcast(s,str); //广播客户发来信息 160 } 161 void DelUserName(HWND hW,SOCKET s,char *str) //删除释放连接的用户登录信息 162 { 163 int i; 164 int ui; 165 ui = GetUserBySocket(s); 166 for(i=0;i<UN;i++) 167 if(Csi[i]==s) 168 { 169 Broadcast(s,str); 170 wsprintf(aa,"%s:%s[%s:%d]",User[ui],str, 171 inet_ntoa(CAi[i].sin_addr),ntohs(CAi[i].sin_port)); 172 Puts(hW,MEMO1,aa); 173 Csi[i]=-1; 174 User[i][0]=0; 175 return; 176 } 177 } 178 void AddUser() //添加建立连接的用户登录信息 179 { 180 int i; 181 for(i=0;i<UN;i++) 182 if(Csi[i]==-1) 183 { 184 Csi[i]=Cs; 185 CAi[i]=CA; 186 User[i][0]=0; 187 break; 188 } 189 } 190 //--------------------------------------------------------------------------- 191 //消息处理 192 LRESULT CALLBACK WndProc(HWND hW, UINT msg, WPARAM wP, LPARAM lP) 193 { 194 int i; 195 switch (msg) 196 { 197 case WM_DESTROY: //关闭程序触发事件 198 WSAAsyncSelect(Ss, hW, 0, 0); //向Windows注销Socket触发事件 199 closesocket(Ss); //释放连接 200 WSACleanup( ); //卸载动态连接库WinSock DLL 201 PostQuitMessage(0); 202 break; 203 case WM_CREATE: //程序初始化触发事件 204 WSAStartup(0x0101,&ws); //装载动态连接库WinSock DLL 205 CreateButton("Send",10,22,50,20,BUTTON1,hW,hInst); //Chat Server的推送信息按钮 206 CreateButton("Start",10,2,50,20,BUTTON2,hW,hInst); //启动服务按钮 207 CreateEdit("127.0.0.1",70,2,180,20,EDIT2,hW,hInst); //Chat Server的IP地址输入框 208 CreateEdit("7777",260,2,90,20,EDIT3,hW,hInst); //Chat Server的Port端口输入框 209 CreateEdit("Hello!",70,22,280,20,EDIT1,hW,hInst); //Chat Server的推送信息输入框 210 CreateMemo("Info.", 2,45,350,120,MEMO1,hW,hInst); //客户登录信息显示窗口 211 SetFocus(GetDlgItem(hW,BUTTON1)); 212 EnableWindow(GetDlgItem(hW,BUTTON1),FALSE); 213 EnableWindow(GetDlgItem(hW,BUTTON2),TRUE); 214 for(i=0;i<UN;i++) //初始化客户登录信息变量 215 { 216 Csi[i]=-1; 217 User[i][0]=0; 218 } 219 break; 220 case WM_USER+1: //Socket触发事件 221 switch(LOWORD(lP)) 222 { 223 case FD_ACCEPT: //Chat Client的建立连接请求 224 d=sizeof(CA); 225 Cs=accept(Ss,(struct sockaddr *) &CA,&d); //接受Chat Client的连接请求 226 AddUser(); //添加建立连接的用户登录信息 227 break; 228 case FD_READ: //收到Chat Client信息 229 d=recv(wP,bb,sizeof(bb),0);//wP=Cs //读接收缓冲区 230 231 bb[d]=0; 232 BroadcastToClients(hW,wP,bb); //向其它客户转发信息或用户登录名注册 233 break; 234 case FD_CLOSE: //Chat Client的释放连接请求 235 wsprintf(bb,"Leave!"); 236 DelUserName(hW,wP,bb); //删除释放连接的用户登录信息 237 break; 238 } 239 break; 240 case WM_COMMAND: //控件触发事件 241 switch(wP) 242 { 243 case BUTTON1: //按下推送信息按钮 244 GetDlgItemText(hW,EDIT1,bb,sizeof(bb)); 245 for(i=0;i<UN;i++) //向登录的客户推送信息 246 { 247 if(Csi[i]==-1) continue; 248 wsprintf(aa,"Server:%s",bb); 249 send(Csi[i],aa,strlen(aa),0); 250 } 251 break; 252 case BUTTON2: //按下启动服务按钮 253 EnableWindow(GetDlgItem(hW,BUTTON2),FALSE); 254 EnableWindow(GetDlgItem(hW,BUTTON1),TRUE); 255 EnableWindow(GetDlgItem(hW,EDIT2),FALSE); 256 EnableWindow(GetDlgItem(hW,EDIT3),FALSE); 257 GetDlgItemText(hW,EDIT2,aa,sizeof(aa)); 258 GetDlgItemText(hW,EDIT3,bb,sizeof(bb)); 259 Ss=socket(AF_INET, SOCK_STREAM,0); //创建TCP套接字Socket 260 SA.sin_family=AF_INET; //Chat Server的属性:地址类型 AF_INET for Internet 261 SA.sin_port = htons(atoi(bb)); //Chat Server的属性:端口 262 SA.sin_addr.s_addr =inet_addr(aa); //Chat Server的属性:IP地址 263 264 bind(Ss,(struct sockaddr *) &SA,sizeof(SA)); //设置socket属性 265 WSAAsyncSelect(Ss,hW,WM_USER+1,FD_ACCEPT|FD_READ|FD_CLOSE); //向Windows注册Socket触发事件 266 listen(Ss,100); //建立连接缓冲区,100个连接 267 Beep(2000,100); 268 break; 269 } 270 break; 271 } 272 return DefWindowProc(hW,msg,wP,lP); 273 } 274 //--------------------------------------------------------------
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //ChatCli.cpp : Defines the entry point for the application. use VC 6.0 2 //========================================================================= 3 //传输控制协议TCP 4 //说明: Chat Client客户端程序 5 //========================================================================= 6 //VC 6.0 add WSOCK32.LIB in Project -> Settings... -> Link 7 #include <winsock.h> 8 #include <stdlib.h> 9 //-------------------------------------------------------------- 10 // Global Variables: 11 HINSTANCE hInst; // 实例句柄,方便各程序访问 12 HWND hWnd; // 主窗口句柄,方便各程序访问 13 char Title[]="Chat-Client"; // 窗口标题 The title bar text 14 int WinX0=250,WinY0=50,WinW=360,WinH=200; // 窗口位置、大小 15 16 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 17 //-------------------------------------------------------------- 18 int APIENTRY WinMain(HINSTANCE hI,HINSTANCE hP,LPSTR lp,int nC) 19 { 20 MSG msg; 21 hInst = hI; // Store instance handle in our global variable 22 WNDCLASS wc; 23 24 memset(&wc,0,sizeof(WNDCLASS)); 25 26 wc.lpfnWndProc = (WNDPROC)WndProc; 27 wc.hInstance = hI; 28 wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); 29 wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1); 30 wc.lpszClassName = "Win32API"; 31 RegisterClass(&wc); 32 //特殊窗口1,始终在顶层,任务栏显示。 33 hWnd=CreateWindowEx(WS_EX_TOPMOST,"Win32API",Title, 34 WS_DLGFRAME|WS_SYSMENU, 35 // WinX0,WinY0,WinW,WinH, // 窗口位置、大小 36 CW_USEDEFAULT,CW_USEDEFAULT,WinW,WinH, // 窗口位置 Windows selects the default position 、大小 37 NULL, NULL, hI, NULL); 38 if(!hWnd) return FALSE; 39 40 ShowWindow(hWnd, nC); 41 // Main message loop: 42 while (GetMessage(&msg, NULL, 0, 0)) 43 { 44 TranslateMessage(&msg); 45 DispatchMessage(&msg); 46 } 47 return msg.wParam; 48 } 49 //-------------------------------------------------------------- 50 //按钮 51 HWND CreateButton(char *Titel,int x0,int y0,int w,int h,int ID,HWND hW,HINSTANCE hInst) 52 { 53 return CreateWindowEx(WS_EX_PALETTEWINDOW,"BUTTON",Titel, 54 WS_VISIBLE | WS_CHILD , 55 x0,y0,w,h, hW,(HMENU)ID,hInst,NULL); 56 } 57 //--------------------------------------------------------------------------- 58 //单行编辑框 59 HWND CreateEdit(char *Titel,int x0,int y0,int w,int h,int ID,HWND hW,HINSTANCE hInst) 60 { 61 return CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT",Titel, 62 WS_VISIBLE | WS_CHILD | 63 ES_LEFT | ES_MULTILINE | WS_HSCROLL , 64 x0,y0,w,h, hW, 65 (HMENU)ID,hInst,NULL); 66 } 67 //--------------------------------------------------------------------------- 68 //多行文本框 69 HWND CreateMemo(char *Titel,int x0,int y0,int w,int h,int ID,HWND hW,HINSTANCE hInst) 70 { 71 return CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT",Titel, 72 WS_VISIBLE | WS_CHILD | 73 ES_LEFT | ES_MULTILINE |ES_READONLY| 74 WS_HSCROLL | WS_VSCROLL, 75 x0,y0,w,h, 76 hW,(HMENU)ID,hInst,NULL); 77 } 78 //--------------------------------------------------------------------------- 79 //向多行文本框中添加文本 80 void Puts(HWND hW,int ID_EDIT,char *str) 81 { 82 int nLen=GetWindowTextLength(GetDlgItem(hW,ID_EDIT)); 83 SendMessage(GetDlgItem(hW,ID_EDIT),EM_SETSEL,nLen,nLen); 84 SendMessage(GetDlgItem(hW,ID_EDIT),EM_REPLACESEL,TRUE,(long)(LPCTSTR)str); 85 nLen=GetWindowTextLength(GetDlgItem(hW,ID_EDIT)); 86 SendMessage(GetDlgItem(hW,ID_EDIT),EM_SETSEL,nLen,nLen); 87 SendMessage(GetDlgItem(hW,ID_EDIT),EM_REPLACESEL,TRUE,(long)(LPCTSTR)"\r\n"); 88 } 89 //--------------------------------------------------------------------------- 90 //按钮 91 #define BUTTON1 501 92 #define BUTTON2 502 93 //--------------------------------------------------------------------------- 94 //单行编辑框 95 #define EDIT1 601 96 #define EDIT2 602 97 #define EDIT3 603 98 #define EDIT4 604 99 //--------------------------------------------------------------------------- 100 //多行编辑框 101 #define MEMO1 701 102 //--------------------------------------------------------------------------- 103 WSADATA ws; 104 SOCKET Ss,Cs; 105 struct sockaddr_in SA,CA; 106 char aa[200]; 107 char bb[200]; 108 int d; 109 //--------------------------------------------------------------------------- 110 //消息处理 111 LRESULT CALLBACK WndProc(HWND hW, UINT msg, WPARAM wP, LPARAM lP) 112 { 113 int i; 114 switch (msg) 115 { 116 case WM_DESTROY: //关闭程序触发事件 117 WSAAsyncSelect(Ss, hW, 0, 0); //向Windows注销Socket触发事件 118 closesocket(Cs); //释放连接 119 WSACleanup( ); //卸载动态连接库WinSock DLL 120 PostQuitMessage(0); 121 break; 122 case WM_CREATE: //程序初始化触发事件 123 WSAStartup(0x0101,&ws); //装载动态连接库WinSock DLL 124 CreateButton("Send",10,22,50,20,BUTTON1,hW,hInst); //发送信息按钮 125 CreateButton("Conn",10,2,50,20,BUTTON2,hW,hInst); //连接Chat Server按钮 126 CreateEdit("127.0.0.1",70,2,120,20,EDIT2,hW,hInst); //Chat Server的IP地址输入框 127 CreateEdit("7777",200,2,60,20,EDIT3,hW,hInst); //Chat Server的Port地址输入框 128 CreateEdit("Name",270,2,80,20,EDIT4,hW,hInst); //用户登录名输入框 129 CreateEdit("Hello!",70,22,280,20,EDIT1,hW,hInst); //发送信息输入框 130 CreateMemo("Info.", 2,45,350,120,MEMO1,hW,hInst); //接受信息显示窗口 131 SetFocus(GetDlgItem(hW,BUTTON2)); 132 EnableWindow(GetDlgItem(hW,BUTTON1),FALSE); 133 break; 134 case WM_USER+1: //Socket触发事件 135 switch(LOWORD(lP)) 136 { 137 case FD_CONNECT: //Chat Server的建立连接应答 138 // Puts(hW,MEMO1,"FD_CONNECT->Ok!"); 139 break; 140 case FD_READ: //收到Chat Server信息 141 d=recv(wP,bb,sizeof(bb),0);//wP=Cs //读接收缓冲区 142 bb[d]=0; 143 wsprintf(aa,"FD_READ->:%s",bb); 144 Puts(hW,MEMO1,bb); 145 break; 146 case FD_CLOSE: //Chat Server的释放连接请求 147 Puts(hW,MEMO1,"Server Stop!"); 148 break; 149 } 150 break; 151 case WM_COMMAND: //控件触发事件 152 switch(wP) 153 { 154 case BUTTON1: //按下发送信息按钮 155 GetDlgItemText(hW,EDIT1,bb,sizeof(bb)); 156 send(Cs,bb,strlen(bb),0); //向Chat Server发送信息 157 break; 158 case BUTTON2: //按下连接Chat Server按钮 159 GetDlgItemText(hW,EDIT2,aa,sizeof(aa)); 160 GetDlgItemText(hW,EDIT3,bb,sizeof(bb)); 161 Cs = socket(PF_INET, SOCK_STREAM, 0); //创建TCP套接字Socket 162 SA.sin_family = PF_INET; //远程Chat Server的属性:地址类型 AF_INET for Internet 163 SA.sin_port = htons(atoi(bb)); //远程Chat Server的属性:端口 164 SA.sin_addr.s_addr =inet_addr(aa); //远程Chat Server的属性:IP地址 165 d=sizeof(SA); 166 i=connect(Cs,(struct sockaddr *)&SA,d); //连接Chat Server 167 if(!i) 168 { //连接Chat Server成功 169 EnableWindow(GetDlgItem(hW,BUTTON2),FALSE); 170 EnableWindow(GetDlgItem(hW,BUTTON1),TRUE); 171 EnableWindow(GetDlgItem(hW,EDIT2),FALSE); 172 EnableWindow(GetDlgItem(hW,EDIT3),FALSE); 173 EnableWindow(GetDlgItem(hW,EDIT4),FALSE); 174 WSAAsyncSelect(Cs,hW,WM_USER+1,FD_CONNECT|FD_READ|FD_CLOSE);//向Windows注册Socket触发事件 175 GetDlgItemText(hW,EDIT4,bb,sizeof(bb)); 176 send(Cs,bb,strlen(bb),0); //连接成功后,向Chat Server发送用户登录名 177 } 178 else 179 Puts(hW,MEMO1,"connect fail!"); //连接Chat Server失败 180 Beep(1000,100); 181 break; 182 } 183 break; 184 } 185 return DefWindowProc(hW,msg,wP,lP); 186 } 187 //--------------------------------------------------------------
第四部分:抓包工具抓取TCP三次握手建立连接的报文
采用方案2:访问百度网站 然后分析tcp报文
1.整体看三次握手过程
首先我们给百度发syn报文
然后百度给我们发syn+ACK报文
最后我们给百度发ACK报文
2.第一步
3.第二步
4.第三步
5.TCP报文格式
源端口: 数据发送方的端口号。
目的端口: 数据接受方的端口号。
序号:本数据报文中的的第一个字节的序号(在数据流中每个字节都对应一个序号)。
确认号:希望收到的下一个数据报文中的第一个字节的序号。
数据偏移:表示本报文数据段距离报文段有多远。
保留:顾名思义,用来保留给以后用的。
紧急比特URG:当值为1时表示次报文段中有需要紧急处理。
确认比特ACK:值为1时确认号有效,值为0时确认号无效。
复位比特RST:值为1时表示TCP连接存在严重的错误,需要重新进行连接。
同步比特SYN:值为1表示这是一个连接请求或连接接受报文。
终止比特FIN: 值为1表示要发送的数据报已经发送完毕,需要释放传送连接。
窗口字段:TCP连接的一端根据缓存空间的大小来确定自己接受窗口的大小,限制发送放的窗口上限。
检验和:用来检验首部和数据两部分的正确性。
紧急指针字段:本报文紧急数据的最后一个字节的序号。
6.UDP报文格式
UDP长度:UDP报文的字节长度(包括首部和数据)。
UDP校验和: 检验UDP首部和数据部分的正确性。
7.IP报文格式
版本:指IP协议的版本。
首部长度:首部的长度
服务类型:如下图:
优先级用来区别优先级别不同的IP报文。
D表示要求有更低的时延。
T表示要求有更高的吞吐量。
R表示要求有更高的可靠性。
总长度:报文的长度。
标识:由于数据报长度超过传输网络的MTU(最大传输单元)而必须分片,这个标识字段的值被复制到所有数据报分片的标识字段中,使得这些分片在达到最终的目的地时可以依照标识字段的内容重新组成原先的数据报。
标志:最低位是MF,MF=1时,表示后面还有分片。
中间位的DF,DF=1时,表示不能分片。
片偏移: 和前面的数据分片相关,是本分片在原先数据报文中相对首位的偏移位。
生存时间:数据报在网络中存活的时间,所允许通过的路由器的最大数量,没通过一个路由器,该值自动减一,如果数值为0,路由器就可以把该数据报丢弃。
协议: 指出数据报携带的数据是使用何种协议,以便目的主机的IP层能知道次数据报上交到哪一个进程(不同协议有一个专门不同的进程处理)。
首部校验位和:对首部进行校验运算。
校验方法 : 在发送端,将IP数据报首部划分为多个16位的二进制序列,并将首部校验和字段置为0,
用反码运算将所有16位序列对位相加后,将得到多的和的反码写入首部校验和字段。
接收端接收到数据报后,将数据报首部的所有字段组织成多个16位的二进制序列,再使用反码运算相加一次
将得到的结果取反。如果结果为0代表没出错,否则出错。
源地址:发送数据报的节点地址。
目的地址:接受数据报的节点地址。