TCP/UDP
一、TCP通信流程
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include "../common/InitSock.h" 2 #include <stdio.h> 3 CInitSock initSock; // 初始化Winsock库 4 int main() 5 { 6 // 创建套接字 7 SOCKET sListen = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 8 if(sListen == INVALID_SOCKET) 9 { 10 printf("Failed socket() \n"); 11 return 0; 12 } 13 // 填充sockaddr_in 结构 14 sockaddr_in sin; 15 sin.sin_family = AF_INET; 16 sin.sin_port = htons(4567); 17 sin.sin_addr.S_un.S_addr = INADDR_ANY; 18 // 绑定这个套接字到一个本地地址 19 if(::bind(sListen, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR) 20 { 21 printf("Failed bind() \n"); 22 return 0; 23 } 24 // 进入监听模式 25 if(::listen(sListen, 2) == SOCKET_ERROR) 26 { 27 printf("Failed listen() \n"); 28 return 0; 29 } 30 // 循环接受客户的连接请求 31 sockaddr_in remoteAddr; 32 int nAddrLen = sizeof(remoteAddr); 33 SOCKET sClient; 34 char szText[] = " TCP Server Demo! \r\n"; 35 while(TRUE) 36 { // 接受新连接 37 sClient = ::accept(sListen, (SOCKADDR*)&remoteAddr, &nAddrLen); 38 if(sClient == INVALID_SOCKET) 39 { 40 printf("Failed accept()"); 41 continue; 42 } 43 printf(" 接受到一个连接:%s \r\n", inet_ntoa(remoteAddr.sin_addr)); 44 // 向客户端发送数据 45 ::send(sClient, szText, strlen(szText), 0); 46 // 关闭同客户端的连接 47 ::closesocket(sClient); 48 } 49 // 关闭监听套接字 50 ::closesocket(sListen); 51 return 0; 52 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include "../common/InitSock.h" 2 #include <stdio.h> 3 CInitSock initSock; // 初始化Winsock库 4 int main() 5 { 6 // 创建套接字 7 SOCKET s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 8 if(s == INVALID_SOCKET) 9 { 10 printf("Failed socket() \n"); 11 return 0; 12 } 13 14 // 也可以在这里调用bind 函数绑定一个本地地址 15 // 否则系统将会自动安排 16 ... 17 // 填写远程地址信息 18 sockaddr_in servAddr; 19 servAddr.sin_family = AF_INET; 20 servAddr.sin_port = htons(4567); 21 // 注意,这里要填写服务器程序(TCPServer 程序)所在机器的IP地址 22 // 如果你的计算机没有联网,直接使用127.0.0.1即可 23 servAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); 24 if(::connect(s, (sockaddr*)&servAddr, sizeof(servAddr)) == -1) 25 { 26 printf("Failed connect() \n"); 27 return 0; 28 } 29 // 接收数据 30 char buff[256]; 31 int nRecv = ::recv(s, buff, 256, 0); 32 if(nRecv > 0) 33 { 34 buff[nRecv] = '\0'; 35 printf(" 接收到数据:%s", buff); 36 } 37 // 关闭套接字 38 ::closesocket(s); 39 return 0; 40 }
二、UDP 编程
(1)服务器端程序设计流程如下。
①创建套接字(socket)。
②绑定 IP 地址和端口(bind)。
③收发数据(sendto/recvfrom)。
④关闭连接(closesocket)。
(2)客户端程序设计流程如下。
①创建套接字(socket)。
②收发数据(sendto/recvfrom)。
③关闭连接(closesocket)。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include "../common/InitSock.h" 2 #include <stdio.h> 3 CInitSock initSock; // 初始化Winsock库 4 int main() 5 { 6 // 创建套接字 7 SOCKET sListen = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 8 if(sListen == INVALID_SOCKET) 9 { 10 printf("Failed socket() \n"); 11 return 0; 12 } 13 // 填充sockaddr_in 结构 14 sockaddr_in sin; 15 sin.sin_family = AF_INET; 16 sin.sin_port = htons(4567); 17 sin.sin_addr.S_un.S_addr = INADDR_ANY; 18 // 绑定这个套接字到一个本地地址 19 if(::bind(sListen, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR) 20 { 21 printf("Failed bind() \n"); 22 return 0; 23 } 24 // 进入监听模式 25 if(::listen(sListen, 2) == SOCKET_ERROR) 26 { 27 printf("Failed listen() \n"); 28 return 0; 29 } 30 // 循环接受客户的连接请求 31 sockaddr_in remoteAddr; 32 int nAddrLen = sizeof(remoteAddr); 33 SOCKET sClient; 34 char szText[] = " TCP Server Demo! \r\n"; 35 while(TRUE) 36 { // 接受新连接 37 sClient = ::accept(sListen, (SOCKADDR*)&remoteAddr, &nAddrLen); 38 if(sClient == INVALID_SOCKET) 39 { 40 printf("Failed accept()"); 41 continue; 42 } 43 printf(" 接受到一个连接:%s \r\n", inet_ntoa(remoteAddr.sin_addr)); 44 // 向客户端发送数据 45 ::send(sClient, szText, strlen(szText), 0); 46 // 关闭同客户端的连接 47 ::closesocket(sClient); 48 } 49 // 关闭监听套接字 50 ::closesocket(sListen); 51 return 0; 52 } 53 // 创建套接字 // 完整代码在UDPServer工程下 54 SOCKET s = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 55 if(s == INVALID_SOCKET) 56 { 57 printf("Failed socket() \n"); 58 return 0; 59 } 60 // 填充sockaddr_in 结构 61 sockaddr_in sin; 62 sin.sin_family = AF_INET; 63 sin.sin_port = htons(4567); 64 sin.sin_addr.S_un.S_addr = INADDR_ANY; 65 // 绑定这个套接字到一个本地地址 66 if(::bind(s, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR) 67 { 68 printf("Failed bind() \n"); 69 return 0; 70 } 71 // 接收数据 72 char buff[1024]; 73 sockaddr_in addr; 74 int nLen = sizeof(addr); 75 while(TRUE) 76 { 77 int nRecv = ::recvfrom(s, buff, 1024, 0, (sockaddr*)&addr, &nLen); 78 if(nRecv > 0) 79 { 80 buff[nRecv] = '\0'; 81 printf(" 接收到数据(%s):%s", ::inet_ntoa(addr.sin_addr), buff); 82 } 83 } 84 ::closesocket(s); 85 86 // 填写远程地址信息 // 完整代码在UDPClient 工程下 87 sockaddr_in addr; 88 addr.sin_family = AF_INET; 89 addr.sin_port = htons(4567); 90 addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); 91 // 发送数据 92 char szText[] = " TCP Server Demo! \r\n"; 93 ::sendto(s, szText, strlen(szText), 0, (sockaddr*)&addr, sizeof(addr));
爱程序 不爱bug
爱生活 不爱黑眼圈
我和你们一样 我和你们不一样
我不是凡客 我要做geek