gpt4 book ai didi

c++ - 使用 epoll 的套接字服务器在断开连接时给出未知字节

转载 作者:行者123 更新时间:2023-11-30 18:02:42 25 4
gpt4 key购买 nike

我有一个 C++ 套接字服务器,我正在使用 epoll。我正在向服务器发送一个包含 HeaderPacket 和 NormalPacket 的字符。首先我读取 HeaderPacket,然后读取 NormalPacket。

现在的问题是,当我关闭客户端时(我试图使用 close 和 shutdown - 相同的输出),我在第一个recv(读取 header 数据包的那个)上以及在段错误之后得到一些奇怪的字节。

此外,当我将内容字符的大小从 HeaderPacket 更改为另一个值(例如 120)时,我不会出现段错误,但当我将其设置为 40 或其他值时,我会出现段错误。

#define BUFFERSIZE 256
#define CHARSIZE 40

这是我用来阅读的功能:

void PacketHandler::ReadBytes(int fd, struct HeaderPacket &hp, char buffer[])

{

int reading = 0;

ssize_t hpCount, cpCount;

char hpBuffer[6];



hpCount = recv(fd, hpBuffer, 6, 0);

if(hpCount <= 0)

{

reading = 1;

} else {

this->UnserializeHeaderPacket(hpBuffer, hp);

print(DEBUG, Helpers::IntegerToString(hp.length));

cpCount = hp.length;

char cpBuffer[cpCount];

memset(cpBuffer, 0, sizeof(cpBuffer));

char* iterator = cpBuffer;

int bytesLeft = sizeof(cpBuffer) - sizeof(char);

print(DEBUG, Helpers::IntegerToString(bytesLeft));

if(bytesLeft < 0)

{

reading = 1;

}

while(bytesLeft > 0)

{

ssize_t curr;

curr = recv(fd, iterator, bytesLeft, 0);



if(curr == -1)

{

if(errno != EAGAIN)

{

reading = 1;

print(WARNING, "reading error at content packet");

}

break;

} else if(curr == 0) {

reading = 1;

break;

}



iterator += curr;

bytesLeft -= curr;





}



memcpy(buffer, cpBuffer, sizeof cpBuffer);

}



if(reading)

{

print(NOTICE, "Closed connection with the descriptor " + Helpers::IntegerToString(fd));

close(fd);

}

}

这里是epoll的函数

void EventHandler::RunningLoop(int fd)

{

while(1)

{

int availableEvents, i;



availableEvents = epoll_wait(this->efd, this->events, MAXEVENTS, -1);

for(i = 0; i < availableEvents; i++)

{

if(this->events[i].data.fd == fd)

{

// Accepting new connection

this->AcceptClient(fd);

continue;

}

else if((this->events[i].events & EPOLLERR) || (this->events[i].events & EPOLLHUP) || (!(this->events[i].events & EPOLLIN)))

{

print(WARNING, "epoll error on reading from fd");

close (this->events[i].data.fd);

continue;

}

else if(this->events[i].events & EPOLLRDHUP)

{

print(WARNING, "intern close socket");

close (this->events[i].data.fd);



} else {

// Reading packets

this->run->InitializePacket(this->events[i].data.fd); // cals the read function

}

}

}



free(this->events);

close(fd);

}

我的数据包:

struct HeaderPacket

{

uint16_t opcode;

uint32_t length;

};



struct HelloWorldPacket

{

uint16_t byteOrder;

char content[CHARSIZE];

};

序列化函数:

void PacketHandler::SerializeHeaderPacket(HeaderPacket packet, char buffer[])

{

uint16_t u16;

uint32_t u32;



u16 = htons(packet.opcode);

memcpy(buffer+0, &u16, 2);

u32 = htonl(packet.length);

memcpy(buffer+2, &u32, 4);

}



void PacketHandler::UnserializeHeaderPacket(char buffer[], HeaderPacket &packet)

{

uint16_t u16;

uint32_t u32;



memcpy(&u16, buffer+0, 2);

packet.opcode = ntohs(u16);

memcpy(&u32, buffer+2, 4);

packet.length = ntohl(u32);

}



void PacketHandler::SerializeHelloWorldPacket(HelloWorldPacket packet, char buffer[])

{

uint16_t u16;



u16 = htons(packet.byteOrder);

memcpy(buffer+0, &u16, 2);

memcpy(buffer+2, &packet.content, sizeof packet.content);

}



void PacketHandler::UnserializeHelloWorldPacket(char buffer[], HelloWorldPacket &packet)

{

uint16_t u16;



memcpy(&u16, buffer+0, 2);

packet.byteOrder = ntohs(u16);



strcpy(packet.content, buffer+2);



}

这就是我向服务器发送数据的方式:

int EventHandler::SendHelloWorld(int fd)

{

HeaderPacket hp;

HelloWorldPacket hc;

char buffer[256];

int sendResult;

char message[] = "hello_first_message\r\n";





hp.opcode = HELLOWORLD;

hp.length = sizeof message;

memcpy(hc.content, message, sizeof message);





packets->SerializeHeaderPacket(hp, buffer);

packets->SerializeHelloWorldPacket(hc, buffer+6);



sendResult = write(fd, buffer, sizeof buffer);







return sendResult;



}

感谢您的帮助。

最佳答案

我已经发现问题了。当我写入服务器时,我使用 sizeof buffer ,缓冲区长度为 256,但我不读取 256 字节。

感谢您的帮助。

关于c++ - 使用 epoll 的套接字服务器在断开连接时给出未知字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8986277/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com