-
socket error?
I'm having a problem sending and receiving packets. When I send a packet I send the size in two bytes a flag in two bytes and then an encrypted packet. (I'm just using a week xor encryption for now.) When I receive I get the size, wait until I've received that amount of bytes and then process the message according to its flag. Everything was working fine until I added another case for chat. The client can send the chat to the server perfectly but for some reason the client isn't receiving the chat from the server.
The problem starts in the function sock_send(). I send the message like I've explained. That works fine. I receive the message in player::receive_instruction(). The message is received perfectly. It goes into case 2 and processes perfectly. I output the socket the message was received from and the socket the message is going to (Which for this test they are supposed to be the same, and they are.) don't worry about the code after that, it has nothing to do with the problem. Then the message is received with the function sock_receive(). The message is processed like every other message (It works fine with the other messages I have so far.) and then goes into the function process_instruction(). It should go into case 2, but it doesn't, and to make things worse it doesn't go into case 0, 1, or default. Which means that the message must have never been received from by the client. Which doesn't make any sense because I send the message the exact same way I send every other message and they are all received.
Can anyone see where I've made a mistake? Thank you for your time.
PHP Code:
void send_gnt(int sockfd, char *buff, int len)
{
while (len > 0)
{
int nSent = send(sockfd, buff, len, 0);
if (nSent > 0)
{
len -= nSent;
buff += nSent;
}
}
}
void player::send_instruction(int sockfd, char *sbuff, int size, int keyval)
{
char buffer[2];
pack(size, buffer);
char key[6] = "";
sprintf(key, "%05d", keyval);
crypt_comp(sbuff, size, 2);
crypt_xor(sbuff, key, size, 6, 2);
send_gnt(sockfd, buffer, 2);
send_gnt(sockfd, sbuff, size);
}
void player::receive_instruction()
{
// <-- start receive instruction
char buffer[1027];
int nRcvd = 0;
unsigned int iLen = 2;
bool gotLen = 0;
do
{
int rc = recv(get_sock(), &buffer[nRcvd], iLen, 0);
if (rc > 0)
{
nRcvd += rc;
if ((!gotLen) && (nRcvd > 1))
{
iLen = unpack(buffer[0], buffer[1]);
gotLen = true;
}
}
}
while ((!gotLen) || (nRcvd < iLen));
// end receive instruction -->
// <-- start process instruction
unsigned int value = unpack(buffer[2], buffer[3]);
char key[6] = "";
sprintf(key, "%05d", value);
crypt_comp(buffer, iLen + 2, 4);
crypt_xor(buffer, key, iLen + 2, 6, 4);
switch (value)
{
case(0): // instruction = create player
{
// code...
}
case(1):
{
// code...
}
case(2): // instruction = player chat
{
char a = buffer[4];
// <-- start copy message
string message;
char send[iLen - 2];
pack(2, send);
send[2] = a;
int i = 5;
char b = buffer[5];
while (b != '\0')
{
message += b;
send[i - 2] = b;
i++;
b = buffer[i];
}
// end copy message -->
if (a == 0x01)
{
// <-- start general chat
// - sent to all players
for (int i = 0; i < engine::playerVector.size(); i++)
{
cout << get_sock() << " - " << engine::playerVector[i]->get_sock() << endl;
send_instruction(engine::playerVector[i]->get_sock(), send, iLen - 2, 2);
}
}
else if (a == 0x02)
{
// <-- start whisper chat
// - sent only to one player
int pos = message.find(':', message.size());
string pname = message.substr(pos);
message.erase(0, pos);
// <-- start delete space
if (message[0] == ' ')
{
pname.erase(0, 1);
}
// end delete space -->
for (int i = 0; i < engine::playerVector.size(); i++)
{
if (engine::playerVector[i]->get_name() == pname)
{
send_instruction(engine::playerVector[i]->get_sock(), send, iLen - 2, 2);
send_instruction(get_sock(), send, iLen - 2, 2);
}
else
{
char p[2];
pack(2, p);
send_instruction(get_sock(), p, 2, 2);
}
}
}
else
{
char p[2];
pack(2, p);
send_instruction(get_sock(), p, 2, 2);
}
}
}
// end process message -->
}
exVal sock_send(double size, char *buff)
{
if (size > 1023)
{
return (0);
}
else
{
char buffer[2];
pack(static_cast<int>(size), buffer);
unsigned int keyval = unpack(buff[0], buff[1]);
char key[6] = "";
sprintf(key, "%05d", keyval);
crypt_comp(buff, static_cast<int>(size), 2);
crypt_xor(buff, key, static_cast<int>(size), 6, 2);
send_gnt(engine::esock.sock, buffer, 2);
send_gnt(engine::esock.sock, buff, static_cast<int>(size));
return (1);
}
}
void process_instruction(char *buffer, int iLen)
{
unsigned int value = unpack(buffer[2], buffer[3]);
char flag[6] = "";
sprintf(flag, "%05d", value);
crypt_comp(buffer, iLen + 2, 4);
crypt_xor(buffer, flag, iLen + 2, 6, 4);
switch (value)
{
case(0): // creation accept
case(1): // login request
{
char instruction[2];
instruction[0] = buffer[4];
instruction[1] = '\0';
strcat(engine::exbuff, flag);
strcat(engine::exbuff, instruction);
break;
}
case(2): // chat
{
char instruction[iLen - 4];
int i = 0;
while (i < iLen - 3)
{
instruction[0] = buffer[i + 4];
i++;
}
strcat(engine::exbuff, flag);
strcat(engine::exbuff, instruction);
break;
}
default: int i = 0; while (i == 0) {;}
}
}
exStr sock_receive()
{
engine::fdset = engine::fds;
engine::sr = select(1, &engine::fdset, NULL, NULL, &engine::selectTime);
if (engine::sr == 1)
{
if (FD_ISSET(engine::esock.sock, &engine::fdset))
{
char
buffer[1027] = "",
flag[6] = "";
int nRcvd = 0;
unsigned int iLen = 2;
bool gotLen = 0;
engine::exbuff[0] = '\0';
do
{
int rc = recv(engine::esock.sock, &buffer[nRcvd], iLen, 0);
if (rc > 0)
{
nRcvd += rc;
if ((!gotLen) && (nRcvd > 1))
{
iLen = unpack(buffer[0], buffer[1]);
gotLen = true;
}
}
else
{
if (rc == -1)
{
engine::sockRcvErr = -1;
}
if (rc == 0)
{
engine::sockRcvErr = 0;
}
}
}
while ((!gotLen) || (nRcvd < iLen));
engine::sockRcvErr = 0;
process_instruction(buffer, iLen);
return (engine::exbuff);
}
else
{
engine::sockRcvErr = 2;
}
}
else
{
engine::sockRcvErr = 3;
}
return ("");
}
-
Well if it got into sock_receive(), but never got into process_instruction(), you may need to check the value engine::sockRcvErr. Either print it to a log file or to the screen.
It looks like there's no way it could have gotten into process_instruction, and skipped the cases. It would have at least hit the default case.
-
The message is never getting sent to the client. I don't see how thats possible since I'm sending to the socket I received from. And its working with every other case I use. Can you think of anything that would make it not send the information?
-
Sorry for the double post. I've found out about all I can find out. I went to the server and output the messages as they were being sent and then to the client and output them as they were being received. The server shows that it is sending the message but the client is never receiving it. I've tested over and over again and constantly get the same results. Does anyone know what could be causing this?
-
>Can you think of anything that would make it not send the information?
Not really. Maybe there's something different in the format of the packet.
Code:
> default: int i = 0; while (i == 0) {;}
If it happens to hit this case within function process_instruction(), wouldn't it just loop forever?
-
Yes. I put that in there so that it would crash if something went wrong (I'm just testing it right now thats not what I actually want to happen.) I mean the server is telling me its sending to the same socket it received from but the client is telling me its never receiving anything. I check how many bytes were sent and print those bytes out and sure enough its what its supposed to be sending. But still its never received. Could it be something wrong with the fdset possibly?