C++使用多线程实现高并发访问指定服务器和网站 客户端和服务端代码
时间: 2023-11-09 08:05:37 浏览: 104
C++语言实现的线程池,结合windowsIOCP完成端口,实现socket高并发服务端程序.zip
这是一个比较复杂的问题,需要对网络编程和多线程编程有一定的了解。以下是一个简单的客户端和服务端代码示例,仅供参考。
服务端代码:
```cpp
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
// 服务端监听端口
const int PORT = 8080;
// 最大连接数
const int MAX_CONNECTIONS = 10;
// 互斥锁和条件变量
mutex mtx;
condition_variable cv;
// 任务队列
queue<SOCKET> tasks;
// 线程函数
void worker_thread()
{
while (true)
{
// 等待任务队列非空
unique_lock<mutex> ul(mtx);
cv.wait(ul, []() { return !tasks.empty(); });
// 取出一个任务
SOCKET client_socket = tasks.front();
tasks.pop();
// 处理任务
char buf[1024];
int n = recv(client_socket, buf, sizeof(buf), 0);
send(client_socket, buf, n, 0);
// 关闭连接
closesocket(client_socket);
}
}
int main()
{
// 初始化Winsock
WSADATA wsa;
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
cerr << "WSAStartup failed" << endl;
return 1;
}
// 创建监听套接字
SOCKET listen_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (listen_socket == INVALID_SOCKET)
{
cerr << "socket failed" << endl;
return 1;
}
// 绑定地址
sockaddr_in addr = { 0 };
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(PORT);
if (bind(listen_socket, (sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR)
{
cerr << "bind failed" << endl;
return 1;
}
// 监听端口
if (listen(listen_socket, MAX_CONNECTIONS) == SOCKET_ERROR)
{
cerr << "listen failed" << endl;
return 1;
}
// 创建工作线程
thread workers[4];
for (int i = 0; i < 4; i++)
{
workers[i] = thread(worker_thread);
}
// 接受连接并加入任务队列
while (true)
{
SOCKET client_socket = accept(listen_socket, NULL, NULL);
if (client_socket == INVALID_SOCKET)
{
cerr << "accept failed" << endl;
continue;
}
// 加入任务队列
unique_lock<mutex> ul(mtx);
tasks.push(client_socket);
cv.notify_one();
}
// 关闭监听套接字
closesocket(listen_socket);
// 关闭Winsock
WSACleanup();
return 0;
}
```
客户端代码:
```cpp
#include <iostream>
#include <thread>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
// 服务器地址和端口
const char* SERVER_ADDR = "127.0.0.1";
const int PORT = 8080;
// 发送和接收数据
void send_data(SOCKET s)
{
char buf[1024] = "hello";
send(s, buf, sizeof(buf), 0);
}
void recv_data(SOCKET s)
{
char buf[1024];
int n = recv(s, buf, sizeof(buf), 0);
buf[n] = '\0';
cout << buf << endl;
}
int main()
{
// 初始化Winsock
WSADATA wsa;
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
cerr << "WSAStartup failed" << endl;
return 1;
}
// 创建套接字
SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s == INVALID_SOCKET)
{
cerr << "socket failed" << endl;
return 1;
}
// 连接服务器
sockaddr_in addr = { 0 };
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(SERVER_ADDR);
addr.sin_port = htons(PORT);
if (connect(s, (sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR)
{
cerr << "connect failed" << endl;
return 1;
}
// 发送和接收数据
send_data(s);
recv_data(s);
// 关闭套接字
closesocket(s);
// 关闭Winsock
WSACleanup();
return 0;
}
```
需要注意的是,以上代码仅仅是一个简单的示例,实际应用中还需要考虑许多因素,如线程池的大小、任务队列的容量、异常处理等等。同时,也需要适当地添加互斥锁和条件变量来保证线程安全。
阅读全文