PDA

View Full Version : C Sockets. Help.



Unregistered
04-23-2002, 08:07 PM
I have a simple yet very annoying question.

this is the method of what i'm doing.

CREATING SOCKET
CONNECTING...
RESPONSE1: DEAMON BANNER
SEND COMMAND.
RESPONSE2: RESPONSE OF ABOVE SEND.

now response2 is the same as response1.

why the hell is that?

here's my code:


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>

class libfreedb {
public:
void setInfo(const char *theHost = "freedb.freedb.org", int thePort = 8880);

int SignonBanner(); // Stage one of the signin
int Handshake(); // Stage two of the signin

private:
int NewSocket();
void CloseSocket();
int ClearBuffer();

int Socket; // Actual Socket discriptor
const char *Hostname; // Host address, freedv.freedb.org is recommended.
int Port; // Port, 8880.
};





// Name: NewSocket()
// Use: Everytime you need to query the server, it will create a new socket.
// Returns: -1 on fail, 0 on success.
int libfreedb::NewSocket()
{
struct hostent *he;
struct sockaddr_in their_addr; // connector's address information
if ((he=gethostbyname(this->Hostname)) == NULL) { // get the host info
perror("gethostbyname");
return -1;
}
if ((this->Socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
return -1;
}
their_addr.sin_family = AF_INET; // host byte order
their_addr.sin_port = htons(this->Port); // short, network byte order
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
memset(&(their_addr.sin_zero), '\0', 8); // zero the rest of the struct
if (connect(this->Socket, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1) {
perror("connect");
return -1;
}
return 0; // Successful.
}

// Name: CloseSocket()
// Use: Closes the socket connection.
// Returns: void.
void libfreedb::CloseSocket()
{
close(this->Socket);
}

int libfreedb::SignonBanner()
{
if(this->NewSocket() < 0) {
return -1; // Failed.
}

// Send the Command.
int theCommandLen, theBytesSent;
char *theCommand = "cddb hello fod 86.22.33.44 impel v0.1rc\r\n\0";
theCommandLen = strlen(theCommand);
theBytesSent = send(this->Socket, theCommand, theCommandLen, 1);
// End

// Clear Buffer
//this->ClearBuffer();
//this->Socket = NULL;

// Recive Response.
int theBytesReceived;
char theRecvBuffer[3];
theBytesReceived = recv(this->Socket, theRecvBuffer, 3, 0);
if(theBytesReceived < 3) {
perror("recv");
return -1;
}
theRecvBuffer[3] = '\0';

printf("%s", theRecvBuffer);

if(strcmp(theRecvBuffer, "200") != 0) {
return -1;
}



this->CloseSocket();
return 0; // Everything went ok.
}

// Name: setInfo(const char *theHost = "freedb.freedb.org", int thePort = 8880)
// Use: When the new class is declared, this will set the server to connect to. If no arguments are passed, default is used.
// Returns: void.
void libfreedb::setInfo(const char *theHost = "freedb.freedb.org", int thePort = 8880)
{
this->Hostname = theHost;
this->Port = thePort;
}

int libfreedb::ClearBuffer()
{
int BufByte;
while(recv(this->Socket,(void*)&BufByte,1,0)>0) {
if(BufByte == '\r') {
recv(this->Socket,(void*)&BufByte,1,0);
return 0;
}
}
return -1;
}

int main()
{
libfreedb c;

c.setInfo(); // No parameters, so using defaults.
c.SignonBanner();
return 0;
}



Please help me out with this.

Deckard
04-24-2002, 05:37 AM
Is this from executing your application twice, or are you expecting two reponses from one run? As far as I can see, you are sending one message and waiting for one three-byte response. The response will be the first three bytes of the server's banner message.


Originally posted by Unregistered
theBytesSent = send(this->Socket, theCommand, theCommandLen, 1);Also, you are sending your message out of band. Was this your intention?

Unregistered
04-24-2002, 09:39 AM
dont think so. what does that mean?

Deckard
04-24-2002, 10:07 AM
Originally posted by Unregistered
dont think so. what does that mean? Set the 'flags' argument of your send() call to zero (the flags argument is the fourth and final argument).

Some protocols have two (or more) 'bands' or channels for a single communication session. One band for normal traffic, and a second for control codes. If you indicate a message is to be sent out-of-band, the message is treated as a control code (in reality, the significance of sending a message out-of-band differs from protocol to protocol).

TCP does not have multiple bands. Any messages sent as out-of-band over TCP are simply marked 'urgent'. That is, the message is handled immediately upon receipt, regardless of the amount of incoming data queued on the socket.

Unregistered
04-24-2002, 11:46 AM
so what should it be?

Deckard
04-24-2002, 12:15 PM
Originally posted by Unregistered
so what should it be? Set the 'flags' argument of your send() call to zero (the flags argument is the fourth and final argument).