Windows创建TCP Server

58 阅读1分钟


#include <iostream>
#include <string.h>
#ifdef WIN32
#include <windows.h>
#define socklen_t int 
#else
#include <sys/socket.h>  // Linux平台引用这个头文件
#include <arpa/inet.h>
#include <unistd.h>
#define closesocket close  // Linux 中使用close关闭,这里定义一个宏进行替换
#endif

#include <thread>

using namespace std;

// 创建线程处理类
class TcpThread {
public:
	void Main() {
		// 接收客户端数据

		char buf[1024] = { 0 };

		for (;;)
		{
			int recvlen = recv(client, buf, sizeof(buf) - 1, 0);

			if (recvlen <= 0) break;
			buf[recvlen] = '\0';
			if (strstr(buf, "quit") != NULL) {
				char re[] = "quit success!\n";
				send(client, re, strlen(re) + 1, 0); // strlen(re) + 1中的+1表示将\0发给客户端
				break;
			}

			// 发送数据给客户端
			int sendlen = send(client, "ok\n", 4, 0);


			printf("recv %s\n", buf);
		}

		closesocket(client);
	}

	int client = 0;

};

int main(int argc, char* argv[])
{
#ifdef WIN32
	WSADATA ws;

	WSAStartup(MAKEWORD(2, 2), &ws); // 标记动态库计数加1
#endif

	int sock = socket(AF_INET, SOCK_STREAM, 0);

	if (sock == -1)
	{
		printf("create socket failed\n");
		return -1;
	}

	unsigned short port = 8080;
	if (argc > 1)
	{
		port = atoi(argv[1]);
	}

	sockaddr_in saddr;
	saddr.sin_family = AF_INET; // 使用的协议
	saddr.sin_port = htons(port);      // 设置端口号,需要将本地字节序转换为网络字节序
	saddr.sin_addr.s_addr = htonl(0);  // 绑定的ip地址

	// 开始绑定
	if (::bind(sock, (sockaddr*)&saddr, sizeof(saddr)) != 0) {
		printf("bind port %d failed\n", port);

		return -2;
	}

	printf("bind port %d success\n", port);

	printf("[%d]", sock);

	// 监听

	listen(sock, 10);  // 第一个参数为套接字描述符,指明创建连接的套接字。第二个参数表示套接字使用的队列的长度,指定在请求队列中允许的最大请求数

	for (;;) {
		sockaddr_in caddr;
		socklen_t len = sizeof(caddr);

		// 读取连接信息
		int client = accept(sock, (sockaddr*)&caddr, &len);  // client用于与客户端进行通信

		if (client <= 0) break;

		printf("accept client %d\n", client);
		char* ip = inet_ntoa(caddr.sin_addr);
		unsigned short cport = ntohs(caddr.sin_port);

		printf("client ip is %s, port is %d\n", ip, cport);

		TcpThread* th = new TcpThread();
		th->client = client;
		thread sth(&TcpThread::Main, th);
		sth.detach();
	}


	closesocket(sock);

	getchar();

	return 0;
}