c++ socket多客户端连接
C++ socket multi client connect
我编写了一个在Linux中使用epoll的服务器,我想测试一下它在实际环境中可以接受多少个连接。所以我在Windows上编写了一个客户端,客户端创建了许多套接字来连接远程服务器。所以问题是,在服务器接受了大约1700个连接后,客户端创建的新套接字无法连接服务器,错误代码是10060。我把客户端复制到另一个Windows上,同时在两台PC上运行客户端,两者都得到了相同的结果。所以,服务器大约可以接受3400个连接。这个问题可能发生在windows中,我试图修复它:
[HKEY_LOCAL_MACHINE System CurrentControlSet Tcpip 服务参数)
MaxUserPort = 65534 (Decimal)
MaxHashTableSize = 65536 (Decimal)
MaxFreeTcbs = 16000 (Decimal)
但它没有帮助。这是我的服务器代码:
bool GateServer::Init(std::string &port)
{
printf("Init to port %sn", port.c_str());
m_nConnNum = 0;
m_socketfd = CreateAndBindSocket(port);
if (m_socketfd == -1)
{
abort();
}
int result = MakeSocketNonblocking(m_socketfd);
if (result == -1)
{
abort();
}
int z;
int sndbuf = 0; /* Send buffer size */
int rcvbuf = 0; /* Receive buffer size */
socklen_t optlen; /* Option length */
/*
* Get socket option SO_SNDBUF:
*/
optlen = sizeof sndbuf;
z = getsockopt(m_socketfd, SOL_SOCKET, SO_SNDBUF, &sndbuf, &optlen);
/*
* Get socket option SON_RCVBUF:
*/
optlen = sizeof rcvbuf;
z = getsockopt(m_socketfd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, &optlen);
/*
* Report the buffer sizes:
*/
printf("Send buf: %d bytesn", sndbuf);
printf("Recv buf: %d bytesn", rcvbuf);
m_epollfd = epoll_create1(0);
if (m_epollfd == -1)
{
perror("epoll_create");
abort();
}
result = listen(m_socketfd, SOMAXCONN);
if (result == -1)
{
perror("listen");
abort();
}
return true;
}
void GateServer::Run()
{
int result = 0;
struct epoll_event events[MAXEVENTS];
result = AddEpollEvent(m_epollfd, m_socketfd, EPOLLIN | EPOLLET);//读入,边缘触发方式
if (result == -1)
{
perror("epoll_ctl");
abort();
}
/* The event loop */
while (1)
{
int n, i;
n = epoll_wait(m_epollfd, events, MAXEVENTS, -1);
HandleEvents(m_epollfd, events, n, m_socketfd);
}
close(m_socketfd);
}
void GateServer::HandleEvents(int epollfd, struct epoll_event *events, int num, int listenfd)
{
int i;
int fd;
for (i = 0; i < num; i++)
{
fd = events[i].data.fd;
if ((events[i].events & EPOLLERR) ||
(events[i].events & EPOLLHUP))
{
/* An error has occured on this fd, or the socket is not
ready for reading (why were we notified then?) */
fprintf(stderr, "epoll errorn");
printf("events = %dn", events[i].events);
close(fd);
m_nConnNum--;
std::cout << "client " << fd << " disconnect. client num = " << m_nConnNum << std::endl;
continue;
}
else if (fd == listenfd && (events[i].events & EPOLLIN))
{
/* We have a notification on the listening socket, which
means one or more incoming connections. */
HandleAccept(epollfd, listenfd);
}
else if(events[i].events & EPOLLIN)
{
/* We have data on the fd waiting to be read. Read and
display it. We must read whatever data is available
completely, as we are running in edge-triggered mode
and won't get a notification again for the same
data. */
HandleRead(epollfd, fd);
}
else if (events[i].events & EPOLLOUT)
{
}
}
}
void GateServer::HandleAccept(int epollfd, int listenfd)
{
std::cout << "At HandleAccept." << std::endl;
int result;
while (1)
{
struct sockaddr cliaddr;
socklen_t cliaddrlen;
int clifd;
char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
cliaddrlen = sizeof cliaddr;
clifd = accept(listenfd, &cliaddr, &cliaddrlen);
if (clifd == -1)
{
if ((errno == EAGAIN) ||
(errno == EWOULDBLOCK))
{
break;
}
else
{
perror("accept");
break;
}
}
m_nConnNum++;
cout << "connected num = " << m_nConnNum << endl;
result = getnameinfo(&cliaddr, cliaddrlen,
hbuf, sizeof hbuf,
sbuf, sizeof sbuf,
NI_NUMERICHOST | NI_NUMERICSERV);
if (result == 0)
{
// printf("Accepted connection on descriptor %d "
// "(host=%s, port=%s)n", clifd, hbuf, sbuf);
}
/* Make the incoming socket non-blocking and add it to the
list of fds to monitor. */
result = MakeSocketNonblocking(clifd);
if (result == -1)
{
abort();
}
result = AddEpollEvent(epollfd, clifd, EPOLLIN | EPOLLET);
if (result == -1)
{
perror("epoll_ctl");
abort();
}
}
}
void GateServer::HandleRead(int epollfd, int fd)
{
//std::cout << "At HandleRead." << std::endl;
//int done = 0;
while (1)
{
ssize_t count;
char buf[512];
count = read(fd, buf, sizeof(buf));
if (count == -1)
{
/* If errno == EAGAIN, that means we have read all
data. So go back to the main loop. */
if (errno != EAGAIN)
{
perror("read");
//done = 1;
}
break;
}
else if (count == 0)
{
/* End of file. The remote has closed the
connection. */
//done = 1;
if (m_nConnNum <= 0)
{
perror("close");
abort();
}
cout << "client = " << fd << " disconnect." << endl;
close(fd);
m_nConnNum--;
break;
}
//std::cout << "server rec : " << buf << std::endl;
/* Write the buffer to standard output */
int result = write(fd, buf, count);
if (result == -1)
{
perror("write");
abort();
}
}
}
您的发现并未显示您已达到任何类型的服务器限制。它们暴露了客户端每个客户端1700个连接的限制。继续测试,使用更多的客户端主机。
相关文章:
- C++套接字客户端到 Python 服务器未创建连接
- 计算出有多少客户端可以连接到我正在使用的一些tcp服务器代码
- 当客户端在 write() 期间终止连接时,由对等套接字错误重置连接
- 在 QNX 中,如何管理服务器和客户端之间的 IPC 连接?
- C++ Winsock2 客户端未通过远程 IP 连接到服务器
- 客户端 gRPC 连接,C++重新连接?
- 如何在 c++ 中确定 tcp 客户端是否连接
- 检测grpc服务器中关闭的客户端连接
- 仅通过建立一次TCP连接将Recv从客户端发送到服务器套接字
- 如何将请求的客户端连接的 IP 与 QTcpSocket 类中识别的 IP 之一进行比较?
- 为什么信号连接会使套接字客户端对象失效?
- 为什么我的客户端无法连接到服务器?
- 我正在编写一个简单的客户端套接字应用程序,但在连接后服务器收到一个空缓冲区
- gRPC C++尝试在无法访问的 IP 上连接通道时阻止客户端
- C++ 套接字接受,连接的客户端列表
- 多连接客户端套接字应用程序C++
- C [UDP]如何跟踪服务器上的所有连接(客户端)套接字连接
- 使用CORBA-org.omg.CORBA.BAD_PARAM:连接客户端(在VirtualBox上)和服务器(在loc
- 如何连接客户端(在VirtualBox上)和服务器(在localhost上)?我使用CORBA和C++/Java
- 服务器设置在编译时保持打印"connected"即使没有连接客户端