Winsock (Windows Sockets) 是 Windows 操作系统上的网络编程接口,基于 Berkeley Sockets 实现,用于开发网络应用程序。限制仅接受特定IP地址的请求是一种常见的安全措施,可以防止未经授权的访问。
在服务器端代码中,可以在接受连接后检查客户端IP地址,只处理来自允许IP的请求。
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")
int main() {
WSADATA wsaData;
SOCKET ListenSocket, ClientSocket;
struct sockaddr_in server, client;
int client_len;
char allowedIP[] = "192.168.1.100"; // 允许的IP地址
char clientIP[INET_ADDRSTRLEN];
// 初始化Winsock
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
printf("WSAStartup failed\n");
return 1;
}
// 创建监听套接字
ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ListenSocket == INVALID_SOCKET) {
printf("socket failed\n");
WSACleanup();
return 1;
}
// 绑定地址和端口
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(8080);
if (bind(ListenSocket, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR) {
printf("bind failed\n");
closesocket(ListenSocket);
WSACleanup();
return 1;
}
// 开始监听
if (listen(ListenSocket, SOMAXCONN) == SOCKET_ERROR) {
printf("listen failed\n");
closesocket(ListenSocket);
WSACleanup();
return 1;
}
printf("Server listening on port 8080...\n");
while (1) {
// 接受连接
client_len = sizeof(client);
ClientSocket = accept(ListenSocket, (struct sockaddr*)&client, &client_len);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed\n");
continue;
}
// 获取客户端IP
inet_ntop(AF_INET, &(client.sin_addr), clientIP, INET_ADDRSTRLEN);
printf("Connection from: %s\n", clientIP);
// 检查IP是否允许
if (strcmp(clientIP, allowedIP) == 0) {
printf("Allowed IP - processing request\n");
// 处理请求...
send(ClientSocket, "Welcome, authorized client!", 28, 0);
} else {
printf("Blocked IP - closing connection\n");
send(ClientSocket, "Access denied", 13, 0);
}
closesocket(ClientSocket);
}
closesocket(ListenSocket);
WSACleanup();
return 0;
}
另一种方法是通过Windows防火墙配置入站规则,只允许特定IP地址访问指定端口:
对于高性能服务器,可以使用AcceptEx函数并结合GetAcceptExSockaddrs获取客户端地址:
// 使用AcceptEx的示例代码片段
SOCKET AcceptSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
char lpOutputBuf[1024];
int dwReceiveDataLength = 0;
int dwLocalAddressLength = sizeof(SOCKADDR_IN) + 16;
int dwRemoteAddressLength = sizeof(SOCKADDR_IN) + 16;
if (AcceptEx(ListenSocket, AcceptSocket, lpOutputBuf, dwReceiveDataLength,
dwLocalAddressLength, dwRemoteAddressLength, NULL, NULL)) {
SOCKADDR_IN* localAddr = NULL;
SOCKADDR_IN* remoteAddr = NULL;
int localLen = 0, remoteLen = 0;
GetAcceptExSockaddrs(lpOutputBuf, dwReceiveDataLength,
dwLocalAddressLength, dwRemoteAddressLength,
(LPSOCKADDR*)&localAddr, &localLen,
(LPSOCKADDR*)&remoteAddr, &remoteLen);
char clientIP[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &(remoteAddr->sin_addr), clientIP, INET_ADDRSTRLEN);
// 检查IP是否允许...
}
通过以上方法,可以有效地实现Winsock服务仅接受来自特定IP地址的请求。
没有搜到相关的文章