代码拉取完成,页面将自动刷新
#include <iostream>
#include <cstring>
#include "Server.h"
std::vector<Connection> Server::clients;
std::mutex Server::mt; // 必须要用全局 / 静态成员变量
Server::Server() {
this->sockfd = socket(AF_INET, SOCK_STREAM, 0);
this->socketAddr.sin_family = AF_INET;
this->socketAddr.sin_port = htons(PORT_NUM);
this->socketAddr.sin_addr.s_addr = htonl(INADDR_ANY); // 来源IP为0.0.0.0
bind(this->sockfd, (sockaddr *)&this->socketAddr, sizeof(this->socketAddr));
listen(this->sockfd, MAX_CLIENTS);
}
Server::~Server() {
close(this->sockfd);
std::cout << "Server Closed.\n";
}
void Server::run() {
std::cout << "Socket Server Listening\n";
while (true) {
sockaddr_in clientSocketAddr;
unsigned int clientSocketAddrLen = sizeof(clientSocketAddr);
int connFd = accept(
sockfd,
(sockaddr *)&clientSocketAddr,
(socklen_t *)&clientSocketAddrLen
);
Connection connection(
connFd,
inet_ntoa(clientSocketAddr.sin_addr),
ntohs(clientSocketAddr.sin_port)
);
Server::clients.push_back(connection);
std::cout << inet_ntoa(clientSocketAddr.sin_addr)
<< ":"
<< ntohs(clientSocketAddr.sin_port)
<< " connected! \n";
pthread_t connThread; // new thread create
pthread_create(
&connThread,
nullptr,
this->threadStartRoutine,
&connFd // thread fd
);
}
}
void Server::handleClose(int sfd) {
std::cout << "Receive request Connction Close from client sfd = " << sfd << "\n";
// delete a connection in clinet list
for (auto itr = Server::clients.begin(); itr != Server::clients.end(); itr++) {
if ((*itr).fd == sfd) {
Server::clients.erase(itr);
break;
}
}
}
void Server::handleGetTime(int sfd) {
char bufferSend[MAX_BUFFER_SIZE] = {0};
time_t curTime;
time(&curTime);
std::cout << "Receive request getTime from client sfd = " << sfd << "\n";
bufferSend[0] = RES_GET_TIME;
sprintf(bufferSend + strlen(bufferSend), "%ld", curTime);
send(sfd, bufferSend, strlen(bufferSend), 0);
}
void Server::handleGetServerName(int sfd) {
char bufferSend[MAX_BUFFER_SIZE] = {0};
std::cout << "Receive request getServerName from client sfd = " << sfd << "\n";
bufferSend[0] = RES_GET_SERVER_NAME;
gethostname(bufferSend + strlen(bufferSend), sizeof(bufferSend) - sizeof(char));
send(sfd, bufferSend, strlen(bufferSend), 0);
}
void Server::handleGetClinets(int sfd) {
char bufferSend[MAX_BUFFER_SIZE] = {0};
std::cout << "Receive request getClinets from client sfd = " << sfd << "\n";
bufferSend[0] = RES_GET_CLIENTS;
for (auto client : Server::clients) {
const char *clientIp = client.ip.c_str();
int portNum = client.portNum;
sprintf(bufferSend + strlen(bufferSend), "%s", clientIp);
sprintf(bufferSend + strlen(bufferSend), ETX_STR);
sprintf(bufferSend + strlen(bufferSend), "%d", portNum);
sprintf(bufferSend + strlen(bufferSend), EOT_STR);
}
send(sfd, bufferSend, strlen(bufferSend), 0);
}
void Server::handleSend(int sfd, char *bufferRecv) {
char bufferSend[MAX_BUFFER_SIZE] = {0};
std::string msg(bufferRecv + 1);
size_t endOfText = msg.find(ETX_STR);
size_t endOfTrans = msg.find(EOT_STR);
std::string ipAddr = msg.substr(0, endOfText);
int portNum = atoi(msg.substr(endOfText + 1, endOfTrans - (endOfText + 1)).c_str());
std::string content = msg.substr(endOfTrans + 1);
int targetSockfd = -1;
for (auto client : Server::clients) {
if (client.ip == ipAddr && client.portNum == portNum) {
targetSockfd = client.fd;
break;
}
}
std::cout << "Receive request sendMsg from client sfd = " << sfd << "; "
<< "target client: " << ipAddr << ":" << portNum << "\n";
bufferSend[0] = RES_SEND;
if (targetSockfd == -1) {
sprintf(bufferSend + 1, "Target Client Not Found!");
} else {
char msg[MAX_BUFFER_SIZE] = {0};
msg[0] = INDICATION;
sprintf(msg + 1, "%s", content.c_str());
send(targetSockfd, msg, strlen(msg), 0);
sprintf(bufferSend + 1, "Successfully send to target client");
}
send(sfd, bufferSend, strlen(bufferSend), 0);
}
void Server::handleInvalidRequest(int sfd) {
char bufferSend[MAX_BUFFER_SIZE] = {0};
bufferSend[0] = RES_INVALID_REQ;
sprintf(bufferSend + 1, "Invalid Request!");
send(sfd, bufferSend, strlen(bufferSend), 0);
}
void Server::threadRoutine(int sfd) {
const char *welcomePrompt = "Hello, this is server.";
send(sfd, welcomePrompt, strlen(welcomePrompt), 0);
char bufferRecv[MAX_BUFFER_SIZE] = {0};
while (true) {
recv(sfd, bufferRecv, MAX_BUFFER_SIZE, 0);
Server::mt.lock();
char indicator = bufferRecv[0];
switch (indicator) {
case REQ_CONNECTION_CLOSE: {
Server::handleClose(sfd);
break;
}
case REQ_GET_TIME: {
Server::handleGetTime(sfd);
break;
}
case REQ_GET_SERVER_NAME: {
Server::handleGetServerName(sfd);
break;
}
case REQ_GET_CLIENTS: {
Server::handleGetClinets(sfd);
break;
}
case REQ_SEND: {
Server::handleSend(sfd, bufferRecv);
break;
}
default: {
if (indicator != '\0')
Server::handleInvalidRequest(sfd);
break;
}
}
memset(bufferRecv, 0, MAX_BUFFER_SIZE);
Server::mt.unlock();
}
}
void *Server::threadStartRoutine(void *sfd) {
Server::threadRoutine(*(int *)sfd);
return nullptr;
}
int main() {
Server *server = new Server();
server->run();
delete server;
return 0;
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。