进程间通讯(三)--套接字
套接字,是支持TCP/IP的网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,简单的说就是通信的两方的一种约定,用套接字中的相关函数来完成通信过程。按照往例,话不多说,直接上Demo:
Server端:
// SocketServer.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <winsock2.h> #pragma comment(lib, "WS2_32") // 链接到WS2_32.lib #include <WS2tcpip.h> int main() { // 初始化WS2_32.dll WSADATA WsaData = {0}; WORD SocketVersion = MAKEWORD(2, 2); if (WSAStartup(SocketVersion, &WsaData) != 0) { printf("Can't Init Socket!\r\n"); return 0; } // 创建套接字 SOCKET ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//IPv4协议,TCP协议,TCP封包 if (ListenSocket == INVALID_SOCKET) { printf("Failed socket()!\r\n"); return 0; } // 填充sockaddr_in结构 sockaddr_in ServerAddr; ServerAddr.sin_family = AF_INET; ServerAddr.sin_port = htons(4567); ServerAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); // 绑定这个套节字到一个本地地址 if (bind(ListenSocket, (LPSOCKADDR)&ServerAddr, sizeof(ServerAddr)) == SOCKET_ERROR) { printf("Failed bind()! \r\n"); closesocket(ListenSocket); WSACleanup(); return 0; } // 进入监听模式 if (listen(ListenSocket, 2) == SOCKET_ERROR) { printf("Failed listen()!\r\n"); closesocket(ListenSocket); WSACleanup(); return 0; } // 循环接受客户的连接请求 sockaddr_in ClientAddr; int AddrLength = sizeof(ClientAddr); SOCKET AcceptSocket; char SendBuffer[] = "TCP Server! \r\n"; while (TRUE) { // 接受一个新连接 AcceptSocket = accept(ListenSocket, (SOCKADDR*)&ClientAddr, &AddrLength); if (AcceptSocket == INVALID_SOCKET) { closesocket(ListenSocket); WSACleanup(); printf("Failed accept()!\r\n"); continue; } char Buffer[16] = { 0 }; printf("Accept a New Client:%s \r\n", inet_ntop(AF_INET, &ClientAddr.sin_addr,Buffer,16)); // 接收数据 char RecvBuffer[256]; int BufferLength = recv(AcceptSocket, RecvBuffer, 256, 0); if (BufferLength > 0) { RecvBuffer[BufferLength] = '\0'; printf("Recived Buffer:%s", RecvBuffer); } // 向客户端发送数据 send(AcceptSocket, SendBuffer, strlen(SendBuffer), 0); // 关闭同客户端的连接 closesocket(AcceptSocket); } // 关闭监听套节字 closesocket(ListenSocket); WSACleanup(); return 0; }
Client端:
// SocketClient.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <winsock2.h> #pragma comment(lib, "WS2_32") // 链接到WS2_32.lib #include <WS2tcpip.h> int main() { // 初始化WS2_32.dll WSADATA WsaData; WORD SocketVersion = MAKEWORD(2, 2); if (WSAStartup(SocketVersion, &WsaData) != 0) { printf("Can't Init Socket!\r\n"); return 0; } // 创建套接字 SOCKET ClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (ClientSocket == INVALID_SOCKET) { printf(" Failed socket()!\r\n"); WSACleanup(); return 0; } // 也可以在这里调用bind函数绑定一个本地地址 // 否则系统将会自动安排 // 填写远程地址信息 sockaddr_in ServerAddr; ServerAddr.sin_family = AF_INET; ServerAddr.sin_port = htons(4567); // 注意,这里要填写服务器程序(TCPServer程序)所在机器的IP地址 // 如果你的计算机没有联网,直接使用127.0.0.1即可 ServerAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); if (connect(ClientSocket, (sockaddr*)&ServerAddr, sizeof(ServerAddr)) == SOCKET_ERROR) { printf(" Failed connect()!\r\n"); closesocket(ClientSocket); WSACleanup(); return 0; } char SendBuffer[] = "TCP Client Connect! \r\n"; // 向服务端发送数据 send(ClientSocket, SendBuffer, strlen(SendBuffer), 0); // 接收数据 char RecvBuffer[256]; int BufferLength = recv(ClientSocket, RecvBuffer, 256, 0); if (BufferLength > 0) { RecvBuffer[BufferLength] = '\0'; printf(" Recived Buffer:%s", RecvBuffer); } // 关闭套节字 closesocket(ClientSocket); WSACleanup(); getchar(); getchar(); return 0; }