mingw socket编程

作者

QQ群:852283276
微信:arm80x86
微信公众号:青儿创客基地
B站:主页 https://space.bilibili.com/208826118

参考

IPv6 (getaddrinfo & inet_ntop)
mingw中的socket基础
windows下linux下socket编程区别
【坑】winsock2.h和windows.h的include顺序

Please include winsock2.h before windows.h

自己的源文件使用了winsock2.h,而Qt的头文件里包含了windows.h,所以把自己的头文件放到最前面即可。

使用

服务端,

#if defined (WIN32)
    SOCKET sockfd;
#elif defined(__linux__)
    int sockfd;
#endif
	struct addrinfo hints, *servinfo, *p;
	struct sockaddr_in sockaddr;
	unsigned int len;
	int yes = 1;
	int rv;
	char PORT[6];
	sprintf(PORT, "%d", server->port_number);
	memset(&hints, 0, sizeof hints);
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = AI_PASSIVE; // use my IP

	if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) {
#if defined (WIN32)
        fprintf(stderr, "getaddrinfo: WSAGetLastError=%d\n",  WSAGetLastError());
#elif defined(__linux__)
        fprintf(stderr, "getaddrinfo: gai_strerror=%s\n", gai_strerror(rv));
#endif
		return 1;
	}

// loop through all the results and bind to the first we can
	for (p = servinfo; p != NULL; p = p->ai_next) {
		if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol))
				== -1) {
			perror("server: socket");
			continue;
		}

		if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int))
				== -1) {
			perror("setsockopt");
			exit(1);
		}

		if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
#if defined (WIN32)
            closesocket(sockfd);
#elif defined(__linux__)
            close(sockfd);
#endif
			perror("server: bind");
			continue;
		}

		len = sizeof(sockaddr);
        if (getsockname(sockfd, (struct sockaddr *) &sockaddr, &len) != 0) {
#if defined (WIN32)
            closesocket(sockfd);
#elif defined(__linux__)
            close(sockfd);
#endif
			perror("server: getsockname");
			continue;
		}
		server->port_number = ntohs( sockaddr.sin_port );

		break;
	}

	if (p == NULL) {
		fprintf(stderr, "server: failed to bind\n");
		return 2;
	}

	freeaddrinfo(servinfo); // all done with this structure

	if (listen(sockfd, 5) == -1) {
		perror("listen");
		exit(1);
	}
	if (server->debug_level)
		printf("server: waiting for connections...\n");

#if defined (NET_USE_PTHERAD)
    server->fd = sockfd;
    server->run = 1;
    int ret;
    pthread_t tid;
    ret = pthread_create(&tid, NULL, accept_cb, server);
    if(ret != 0)
    {
        printf("%s failed\n", __FUNCTION__);
        return ret;
    }
#elif defined (NET_USE_LIBEV)
    ev_io_init(&server->listen_watcher, accept_cb, sockfd, EV_READ);

    server->listen_watcher.data = server;
    ev_io_start(server->loop, &server->listen_watcher);
#endif

    return 0;
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MinGW 环境下使用 Socket,你需要包含以下头文件: ```c++ #include <winsock2.h> #include <ws2tcpip.h> ``` 同时,需要链接以下库文件: ```c++ -lws2_32 ``` 下面是一个简单的示例代码,实现了一个使用 Socket 监听端口和接收数据的服务器: ```c++ #include <iostream> #include <winsock2.h> #include <ws2tcpip.h> #pragma comment(lib, "ws2_32.lib") int main() { // 初始化 Winsock WSADATA wsaData; int result = WSAStartup(MAKEWORD(2, 2), &wsaData); if (result != 0) { std::cerr << "WSAStartup failed: " << result << std::endl; return 1; } // 创建 Socket SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (serverSocket == INVALID_SOCKET) { std::cerr << "socket failed: " << WSAGetLastError() << std::endl; WSACleanup(); return 1; } // 绑定 Socket sockaddr_in serverAddr; serverAddr.sin_family = AF_INET; serverAddr.sin_addr.s_addr = INADDR_ANY; serverAddr.sin_port = htons(8080); result = bind(serverSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)); if (result == SOCKET_ERROR) { std::cerr << "bind failed: " << WSAGetLastError() << std::endl; closesocket(serverSocket); WSACleanup(); return 1; } // 监听端口 result = listen(serverSocket, SOMAXCONN); if (result == SOCKET_ERROR) { std::cerr << "listen failed: " << WSAGetLastError() << std::endl; closesocket(serverSocket); WSACleanup(); return 1; } std::cout << "Server is listening on port 8080..." << std::endl; // 接收连接并处理数据 while (true) { sockaddr_in clientAddr; int clientAddrLen = sizeof(clientAddr); SOCKET clientSocket = accept(serverSocket, (sockaddr*)&clientAddr, &clientAddrLen); if (clientSocket == INVALID_SOCKET) { std::cerr << "accept failed: " << WSAGetLastError() << std::endl; closesocket(serverSocket); WSACleanup(); return 1; } std::cout << "Client connected: " << inet_ntoa(clientAddr.sin_addr) << std::endl; char buffer[1024]; result = recv(clientSocket, buffer, sizeof(buffer), 0); if (result == SOCKET_ERROR) { std::cerr << "recv failed: " << WSAGetLastError() << std::endl; closesocket(clientSocket); continue; } buffer[result] = '\0'; std::cout << "Received data from client: " << buffer << std::endl; const char* response = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<html><body><h1>Hello, world!</h1></body></html>"; result = send(clientSocket, response, strlen(response), 0); if (result == SOCKET_ERROR) { std::cerr << "send failed: " << WSAGetLastError() << std::endl; } closesocket(clientSocket); } // 关闭 Socket closesocket(serverSocket); // 清理 Winsock WSACleanup(); return 0; } ``` 这段代码创建了一个监听端口为 8080 的服务器,当客户端连接上来并发送数据时,会返回一个简单的 HTTP 响应。需要注意的是,这段代码只是一个简单的示例,实际的网络编程中需要考虑更多的细节问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值