C++ socket编程(TCP)

服务端保持监听客户端, 服务端采用select实现,可以监听多个客户端

客户端源码

在这里插入代码片
```#include <iostream>
//#include 
#include 
#include 
using namespace std;
#pragma comment(lib, "Ws2_32.lib")


int main() {
	WSADATA wd;
	int result;
	result = WSAStartup(MAKEWORD(2, 2), &wd);
	if (result != 0) {
		cout << "WSAStartup error" << endl;
		return 0;
	}

	//创建套接字
	SOCKET c_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (c_socket == INVALID_SOCKET) {
		cout << "socket error" << endl;
		return 0;
	}

	sockaddr_in c_addr;
	inet_pton(AF_INET, "127.0.0.1", &c_addr.sin_addr.S_un.S_addr);
	c_addr.sin_family = AF_INET;
	c_addr.sin_port = htons(8888);
	int len = sizeof(c_addr);
	result = connect(c_socket, (sockaddr*)&c_addr, len);
	if (result == INVALID_SOCKET) {
		cout << "connect error" << endl;
		return 0;
	}
	char sendbuf[1024] = { 0 };
	cout << "client输入数据:";
	cin >> sendbuf;
	//send
	result = send(c_socket, sendbuf, sizeof(sendbuf), 0);
	if (result == SOCKET_ERROR) {
		cout << "client send error" << endl;
		return 0;
	}
	//recv
	char recvbuf[1024] = { 0 };
	result = recv(c_socket, recvbuf, sizeof(recvbuf), 0);
	if (result == 0) {
		cout << "recv error" << endl;
		return 0;
	}
	cout << "servic发送的数据:" << recvbuf << endl;
	//close
	closesocket(c_socket);
	WSACleanup();
	return 0;
}

服务端源码

#include 
//#include 
#include 
#include 
//#include 
//#include 
using namespace std;
//导入动态库
#pragma comment(lib,"ws2_32.lib")

int __cdecl  main(int argc, char** argv) {
	
	WSADATA wd; //创建wd的WSADATA对象
	SOCKET s_socket = INVALID_SOCKET;
	int result;
		//初始化winsock
		//调用WSAStartup
	result = WSAStartup(MAKEWORD(2, 2), &wd);
	if (result != 0) {
		//printf("WSAStartup 失败:d%\n", result);
	}
	//1 创建套接字
	SOCKET ser_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	//判断套接字是否有效
	if (ser_socket == INVALID_SOCKET) {
		cout << "套接字不可用";
		return 0;
	}
	//2 绑定端口和地址 sockaddr_in 是一个结构体
	sockaddr_in addr;
	/*	addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); 使用这个会报错*/
	inet_pton(AF_INET,"127.0.0.1",&addr.sin_addr.S_un.S_addr);
	addr.sin_family = AF_INET;
	addr.sin_port = htons(8888);
	int len = sizeof(addr);
	result = bind(ser_socket, (LPSOCKADDR)&addr, len);
	if (result == SOCKET_ERROR) {
		cout << "socket error"<< result << endl;
		return 0;
	}
	cout << "服务器启动成功,正在等待客户端连接" << endl;



	//3 监听
	if (listen(ser_socket, 5) == SOCKET_ERROR) {
		cout << "listen error" << endl;
	}


	FD_SET  read_set;//创建文件描述集合
	FD_ZERO(&read_set);//清空文件描述集合
	FD_SET(ser_socket, &read_set);//将监听套接字放入文件描述集合
	timeval timeout{ 0,0 };//select超时设置
	
	while (true) {
		FD_SET temp_set;
		FD_ZERO(&temp_set);
		temp_set = read_set;
		int select_num = select(0, &temp_set, NULL, NULL, &timeout);
		if (select_num == SOCKET_ERROR) {
			continue;
		}
		
		for (int i = 0; i < temp_set.fd_count; i++) {
			SOCKET s_df = temp_set.fd_array[i];
			if (s_df == ser_socket) { // 判断监听套接字是否就绪
				//4 接收连接
				//获取客户端IP地址和端口
				sockaddr_in client_addr;
				client_addr.sin_family = AF_INET;
				int client_len = sizeof(client_addr);
				s_socket = accept(ser_socket, (sockaddr*)&client_addr, &client_len);
				if (s_socket == INVALID_SOCKET) {
					cout << "accept error" << endl;
					continue;
				}				
				else {
					cout << "客户端连接成功" << endl;
				}
				char ipbuff[100];
				string remote_host = inet_ntop(AF_INET, &addr.sin_addr.S_un.S_addr, ipbuff, 20);
				cout << "接收到客户机:" << remote_host << " 端口号:" << addr.sin_port << endl;

				// 5接收和发送	
				char recvbuf[1024] = { 0 };
				result = recv(s_socket, recvbuf, sizeof(recvbuf), 0);
				if (result == 0 || result == SOCKET_ERROR) {
					closesocket(s_df);
					FD_CLR(s_df, &read_set);//从集中清除套接字
					cout << "结束连接" << result << endl;
				}
				cout << "client发送的数据:" << recvbuf << endl;

				cout << "service输入数据:";
				char sendbuf[1024] = { 0 };
				cin >> sendbuf;
				result = send(s_socket, sendbuf, sizeof(sendbuf), 0);
				if (result == SOCKET_ERROR) {
					cout << "service send error" << endl;
				}
				if (s_socket == INVALID_SOCKET) {
					cout << "socket error" << endl;
					return 0;
				}
			}
			else {
				
			}
		}
	}

	
	
	while (s_socket) {
		
	}

	// 6关闭
	closesocket(s_socket);

	WSACleanup();

	system("pause");
	return 0;
}

你可能感兴趣的:(C++,SOCKET编程,TCP通信,c++,tcp/ip,开发语言)