TCPServer TCPClient三次握手模拟编程
套接字创建和关闭:
SOCKET socket(int af,int type,int protocal); 套接字类型: SOCK_STREAM 流套接字,TCP提供有连接的可靠传输 SOCK_DGRAM 数据包套接字,UDP提供无连接的不可靠传输 SOCK_RAW 原始套接字
绑定套接字到指定的IP地址和端口号
int bind( SOCKET s,//套接字句柄 const struct sockaddr * name,//关联的本地地址 int namelen//地址的长度 );
监听
int listen( SOCKET s,//套接字 int backlog//最大连接数 )
连接
int accept( SOCKET s, struct sockaddr* addr,//取得对方的地址信息 int* addrlen//指向地址长度 ); int connect( SOCKET s, const struct sockaddr FAR* name,//连接的地址信息 int namelen //结构长度 );
收发数据
int send( SOCKET s, const char FAR* buf,//要发送数据的缓冲区地址 int len,//缓冲区长度 int flags//指定调用方式,通常为0 ); int recv( SOCKET s, char FAR* buf, int len, int );
TCPSERVER端代码:
1 // TCP.cpp : 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 #include <winsock2.h> 6 #include <stdio.h> 7 8 #pragma comment(lib,"WS2_32") 9 class CInitSock 10 { 11 public: 12 CInitSock(BYTE minorVer=2,BYTE majorVer=2) 13 { 14 WSADATA wsaData; 15 WORD sockVersion = MAKEWORD(minorVer,majorVer); 16 if(::WSAStartup(sockVersion,&wsaData)!=0) 17 { 18 exit(0); 19 } 20 } 21 ~CInitSock() 22 { 23 ::WSACleanup(); 24 } 25 }; 26 CInitSock initSock; 27 int _tmain(int argc, _TCHAR* argv[]) 28 { 29 SOCKET sListen = ::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 30 if(sListen == INVALID_SOCKET) 31 { 32 printf("Failed socket()\n"); 33 return 0; 34 } 35 //填充sockaddr_in结构 36 sockaddr_in sin; 37 sin.sin_family = AF_INET; 38 sin.sin_port = htons(4567); 39 sin.sin_addr.S_un.S_addr = INADDR_ANY; 40 //绑定这个套接字的一个本地地址 41 if(::bind(sListen,(LPSOCKADDR)&sin,sizeof(sin)) == SOCKET_ERROR) 42 { 43 printf("Failed bind()\n"); 44 return 0; 45 } 46 //进入监听模式 47 if(::listen(sListen,2) == SOCKET_ERROR) 48 { 49 printf("Failed listen()\n"); 50 return 0; 51 } 52 //循环接受客户的连接请求 53 sockaddr_in remoteAddr; 54 int nAddrLen = sizeof(remoteAddr); 55 SOCKET sClient; 56 char szText[] = "TCP Server Demo!\r\n"; 57 while(TRUE) 58 { 59 //接受新连接 60 sClient=::accept(sListen,(SOCKADDR*)&remoteAddr,&nAddrLen); 61 if(sClient == INVALID_SOCKET) 62 { 63 printf("Failed accept()"); 64 continue; 65 } 66 printf("接受到一个连接:%s\r\n",inet_ntoa(remoteAddr.sin_addr)); 67 //向客户端发送数据 68 ::send(sClient,szText,strlen(szText),0); 69 //关闭同客户端的连接 70 ::closesocket(sClient); 71 } 72 ::closesocket(sListen); 73 return 0; 74 }
TCPClient 端代码:
1 // TCPClient.cpp : 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 #include <winsock2.h> 6 #include <stdio.h> 7 #pragma comment(lib,"WS2_32") 8 class CInitSock 9 { 10 public: 11 CInitSock(BYTE minorVer=2,BYTE majorVer=2) 12 { 13 WSADATA wsaData; 14 WORD sockVersion = MAKEWORD(minorVer,majorVer); 15 if(::WSAStartup(sockVersion,&wsaData)!=0) 16 { 17 exit(0); 18 } 19 } 20 ~CInitSock() 21 { 22 ::WSACleanup(); 23 } 24 }; 25 CInitSock initSock; 26 27 int _tmain(int argc, _TCHAR* argv[]) 28 { 29 SOCKET s= ::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 30 if(s==INVALID_SOCKET) 31 { 32 printf("Failed socket()\n"); 33 return 0; 34 } 35 sockaddr_in servAddr; 36 servAddr.sin_family=AF_INET; 37 servAddr.sin_port=htons(4567); 38 servAddr.sin_addr.S_un.S_addr=inet_addr("49.140.16.244"); 39 if(::connect(s,(sockaddr*)&servAddr,sizeof(servAddr))==-1) 40 { 41 printf("Failed connect()\n"); 42 return 0; 43 } 44 //接受数据 45 char buff[256]; 46 int nRecv=::recv(s,buff,256,0); 47 if(nRecv>0) 48 { 49 buff[nRecv] = '\0'; 50 printf("接受到数据:%s",buff); 51 } 52 ::closesocket(s); 53 return 0; 54 }
结果: