#include <iostream>
#include <winsock.h>
#include <cstdlib>
#include <string>
#include <vector>
SOCKET theSocket;
char *readLine();
char *readLine() {
vector theVector;
char buffer[1];
while (true) {
recv(theSocket, buffer, 1, 0);
if (buffer[0] == '\n') {
char * pChar = new char[theVector.size()];
for (int f = 0; f < theVector.size(); f++) {
pChar[f] = theVector[f];
}
return pChar;
} else {
theVector.push_back(buffer[0]);
}
}
}
int main(int argc, char *argv[]){
WORD version = MAKEWORD(1,1);
WSADATA wsaData;
int nRet;
//start winsock
WSAStartup(version, &wsaData);
//store info about the server
LPHOSTENT lpHostEntry;
lpHostEntry = gethostbyname("www.google.com");
if(lpHostEntry == NULL) {
cerr << "Error at gethostbyname()" << endl;
system("pause");
return -1;
}
//create socket
//over tcp/ip, socket type, protocal
theSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
//SOCKADDR_IN to fill in address info
SOCKADDR_IN saServer;
saServer.sin_family = AF_INET;
//address of server being inserted into addr field
saServer.sin_addr = *((LPIN_ADDR)*lpHostEntry->h_addr_list);
saServer.sin_port = htons(80);
//connect
//server addr, sizeof addr struct
nRet = connect(theSocket, (LPSOCKADDR)&saServer, sizeof(struct sockaddr));
if(nRet == SOCKET_ERROR) {
cerr << "Error at connect()" << endl;
system("pause");
return -1;
}
//connected
std::string strSend("get / HTTP/1.1\n\n");
nRet = send(theSocket, strSend.c_str(), strSend.length(), 0);
if(nRet == SOCKET_ERROR) {
cerr << "Error at send()" << endl;
system("pause");
return -1;
}
//recieve
cout << strSend.c_str() << endl << strSend.length() << endl;
cout << readLine() << endl;
closesocket(theSocket);
//shutdown winsock
WSACleanup();
cout << "done." << endl;
system("pause");
return 0;
}
I think it is the send() line because it does not say there are any errors. I also tried sizeof(strSend.c_str()), but that didn't work either.
[edited by - evilclown on June 17, 2002 4:15:06 PM]
[edited by - evilclown on June 17, 2002 4:15:47 PM]
[edited by - evilclown on June 17, 2002 4:16:26 PM]
[edited by - evilclown on June 17, 2002 4:17:48 PM]
problem with receiving
(No matter what I do, code or source, it removes and double newlines, so it doesn't space between functions...)
What am I doing wrong? It is supposed to recieve the code from google's main page
June 17, 2002 11:11 PM
LP stands for Long (32-bit) Pointer. It meant something when 16-bit OS''s were around. Now that win95+ is 32-bit all pointers are long so it''s obsolete.
Standard debugging practise means you should really use a debugger and look at return values you think are suspect and to check the flow of your program.
Also why would you think doing a sizeof(strSend.c_str()) would help? sizeof returns the size of an element you pass to it while send expects a pointer. strSend.c_str() returns the pointer to the string.
There was one major bug, you were forgetting to null terminate the string you were passing back to cout which was producing rubbish. The second bug was that the response from the server is nto all on one line but as many lines separated by ''cr'' so you needed to use a loop to get all the lines and not just the first. The third bug was that you were not checking for recv() returning <= 0 indicating a graceful close or an error.
Here is your bug fixed code.
Also why would you think doing a sizeof(strSend.c_str()) would help? sizeof returns the size of an element you pass to it while send expects a pointer. strSend.c_str() returns the pointer to the string.
There was one major bug, you were forgetting to null terminate the string you were passing back to cout which was producing rubbish. The second bug was that the response from the server is nto all on one line but as many lines separated by ''cr'' so you needed to use a loop to get all the lines and not just the first. The third bug was that you were not checking for recv() returning <= 0 indicating a graceful close or an error.
Here is your bug fixed code.
#include <iostream.h>#include <winsock.h>#include <cstdlib>#include <string>#include <vector>SOCKET theSocket;char *readLine();// This function reads a line from the server// TODO : Optimise this to not use single byte recv''s however for this demonstration it is finechar *readLine(){ std::vector<char> theVector; char buffer[1]; while (true) { int gotbytes = recv(theSocket, buffer, 1, 0); // If we have no more data or there was an error then return with nothing if (gotbytes <= 0) { return 0; // Since we are using C++ ''0'' looks tidier than NULL } // We can assume that thye recv function having succeeded has put one char in to our buffer // So test for a \n if (buffer[0] == ''\n'') // NOTE : Only works if \n equates to the same \n as the server. Luckily this does. { // +1 for null termination of the string char * pChar = new char[theVector.size()+1]; // Remark : Using "for (int f = 0..." is not valid C++ if we expect to have int f valid after the scope of the cor statement int f; for (f = 0; f < theVector.size(); f++) { pChar[f] = theVector[f]; } // Null terminate the string pChar[f] = 0; // NULL terminate our text line from Google return pChar; } else { theVector.push_back(buffer[0]); } }}int main(int argc, char *argv[]){ WORD version = MAKEWORD(1,1); WSADATA wsaData; int nRet; //start winsock WSAStartup(version, &wsaData); //store info about the server LPHOSTENT lpHostEntry; lpHostEntry = gethostbyname("www.google.com"); if(lpHostEntry == NULL) { cerr << "Error at gethostbyname()" << endl; system("pause"); return -1; } //create socket //over tcp/ip, socket type, protocal theSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //SOCKADDR_IN to fill in address info SOCKADDR_IN saServer; saServer.sin_family = AF_INET; //address of server being inserted into addr field saServer.sin_addr = *((LPIN_ADDR)*lpHostEntry->h_addr_list); saServer.sin_port = htons(80); //connect //server addr, sizeof addr struct nRet = connect(theSocket, (LPSOCKADDR)&saServer, sizeof(struct sockaddr)); if(nRet == SOCKET_ERROR) { cerr << "Error at connect()" << endl; system("pause"); return -1; } //connected std::string strSend("get / HTTP/1.1\n\n"); nRet = send(theSocket, strSend.c_str(), strSend.length(), 0); if(nRet == SOCKET_ERROR) { cerr << "Error at send()" << endl; system("pause"); return -1; } //recieve cout << strSend.c_str() << endl << strSend.length() << endl; cout << "Getting data from server..." << endl; char *linegot; while ( (linegot = readLine()) != 0) { cout << linegot << endl; // Remark : The line from readLine() is not freed, is this what you wanted? } closesocket(theSocket); //shutdown winsock WSACleanup(); cout << "done." << endl; system("pause"); return 0;}
Martin Piper
I don''t know how to debug. Thats why I was outputting all errors and exiting.
whats "Remark : The line from readLine() is not freed, is this what you wanted?" mean? Is it that the line is still taking up memory? I just wanted to output the line, but was following a tutorial.
I wanted to use sizeof because strSend.length() didn''t work, but thats because of the missing null terminator.
Why do I have to manually make a null terminator?
And lines like
nRet = connect(theSocket, (LPSOCKADDR)&saServer, sizeof(struct sockaddr));
if(nRet == SOCKET_ERROR) {
Should I be putting a WSACleanup()?
whats "Remark : The line from readLine() is not freed, is this what you wanted?" mean? Is it that the line is still taking up memory? I just wanted to output the line, but was following a tutorial.
I wanted to use sizeof because strSend.length() didn''t work, but thats because of the missing null terminator.
Why do I have to manually make a null terminator?
And lines like
nRet = connect(theSocket, (LPSOCKADDR)&saServer, sizeof(struct sockaddr));
if(nRet == SOCKET_ERROR) {
Should I be putting a WSACleanup()?
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement