LINUX.ORG.RU

Помогите разобратся. Прога сокеты+http


0

0

Пишу програмку для соединения по http с yande.ru и т.п. Програмка не работает, не могу понят почему. Вчера всю ночь ковырял прогу и поисковики (через оперу =) - ничего не помогает. Вот код программы:

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




#include <stdio.h>
#include <stdlib.h>
#include <signal.h>




//===========================
#define CLNT_PORT 1256;
int mysock;
//===========================
using namespace std;


int main(int argc, char ** argv)
{	
	
	
	{
		//struct hostent * myHost = gethostbyname(argv[1]);
		mysock = socket(AF_INET, SOCK_STREAM, 0);
		if(mysock==-1)
		{			
			return 1;
		};

		struct sockaddr_in mySin;
		memset((char *)&mySin,'\0',sizeof(mySin));
		mySin.sin_family = AF_INET;
		mySin.sin_port = htons(1326);
		mySin.sin_addr.s_addr = INADDR_ANY;
		if(bind(mysock,(struct sockaddr*)&mySin,sizeof(mySin))!=0)
		{			
			return 2;
		};
		
		struct sockaddr_in srvSin;
		srvSin.sin_family = AF_INET;
		struct hostent *hp;
		//hp = gethostbyname("ya.ru");		
		//if (hp==0) {cout<<"!!!";return 123;};
		//memcpy((char*)&srvSin.sin_addr,hp->h_addr_list[0],hp->h_length);
		//cout<< hp->h_addr;
		//srvSin.sin_addr.s_addr = inet_addr(hp->h_addr_list[0]);
		srvSin.sin_addr.s_addr = inet_addr("213.180.204.8");
		srvSin.sin_port = htons(80);
		if(connect(mysock,(const sockaddr*)&srvSin,sizeof(srvSin))!=0)
		{			
			return 3;
		};
		cout<<"1\n";
		char * GetMe = "GET /index.html HTTP/1.0\n\n";
		send(mysock,GetMe,sizeof(GetMe),0);
		cout<<"2\n";
		char *buf[640];
		recv(mysock,buf,10,0);
		cout<<"3\n";
		cout<<buf;
		LogMes("All OK!");
		close(mysock);
		return 0;
		
	}
	return 0;
}
В итоге она открывает соединение, соединение висит, данные уходят, но дойдя до recv происходит что-то непонятное. Я могу печатать на терминале символы, но программа встает и дальше ничего не происходит. Т.е. строки 1 и 2 она на экран выводит, а 3 - нет. Буду благодарен залюбую помощь.

★★★★★

Ответ на: комментарий от hello_world

спсибо за дополнения. все это поправил, но в итоге все так же ничего от сервера получить не удается... может быть там еще есть такие же тупые ошибки?

trex6 ★★★★★
() автор топика

string GetMe = "GET /index.html HTTP/1.0\r\n\r\n";
send(mysock, GetMe.c_str(), GetMe.size(), 0);

char buf[640];
memset(&buf, 0, 640);
recv(mysock, &buf, 10, 0);
cout << string(buf);

smh ★★★
()
Ответ на: комментарий от true_admin

Господа, извиняюсь, что вас тут побеспокоил.
Сейчас все заработало. Но ошибку в том коде я так и не нашел!!!
Переписал все по новой и вот что получилось:
[code]
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h> 
#include <unistd.h>

#define BUF_SIZE 256

int main(int argc, char ** argv)
{
    int sock, port;
    struct sockaddr_in serv_addr;
    struct hostent *server;
    char * buf = "GET /cgi-bin/splash\n\rHTTP1.1\n\rHost edu.mail.ru\n\r\n\r";
    char bufR[BUF_SIZE];
    int readed;

    printf("Hello3\n");
    port = atoi("80");
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0)
    {
      printf("socket() failed: %d", errno);
      return EXIT_FAILURE;
    }
    server = gethostbyname("edu.mail.ru");
    if (server == NULL) 
    {
      printf("Host not found\n");
      return EXIT_FAILURE;
    }
    memset((char *) &serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    memcpy(&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length);
    serv_addr.sin_port = htons(port);
    if (connect(sock,(const sockaddr*) &serv_addr, sizeof(serv_addr)) < 0) 
    {
      printf("connect() failed: %d", errno);
      return EXIT_FAILURE;
    }
    //printf(">");
    //memset(buf, 0, BUF_SIZE);
    //fgets(buf, BUF_SIZE-1, stdin);
    send(sock, buf, strlen(buf),0);
    memset(bufR, 0, BUF_SIZE);
    readed = recv(sock, bufR, BUF_SIZE-1,0);
    while(readed>0)
   {	
       printf("%s\n",bufR);
       readed = recv(sock, bufR, BUF_SIZE-1,0);
   }
    close(sock);
    return 0;
}
[/code]
Если кто-то не пожалеет времени и в итоге сможет мне объяснить, что в предыдущем коде было не так - огромное спасибо скажу!

trex6 ★★★★★
() автор топика
Ответ на: комментарий от trex6

Сниффер - хороший совет. sniffit, например. С его помощью сравни, что передает одна программа, а что другая, и скорее всего все станет ясно.

ratatosk
()
Ответ на: комментарий от trex6

определенно неплохоб узнать про это: #include <errno.h> ; и все вызовы функций проверять на наличие ошибок ( recv) ну при наличии ошибки вызывать типа: perror("типа тут ошибко: ")

hello_world
()
Ответ на: комментарий от trex6

> что в предыдущем коде было не так - огромное спасибо скажу!

В оригинале ты делаешь bind (на порт взятый от потолка), а потом - connect, хотя тебе нужен клиент; в переделанной проге - ты делаешь только connect. Bind тебе как раз и мешал, судя по всему.

Клиентский порт сам будет назначен системой; в общем случае bind нужен серверу, клиенту - нет.

Spectr ★★★
()
Ответ на: комментарий от Spectr

"A newly created TCP socket has no remote or local address and is not fully specified. To create an outgoing TCP connection use connect(2) to establish a connection to another TCP socket. To receive new incoming connections, first bind(2) the socket to a local address and port and then call listen(2) to put the socket into the listening state. ..."

- man 7 tcp

Spectr ★★★
()
Ответ на: комментарий от trex6

особо код не смотрел, но в изначальном варианте был неправильный гет запрос, а во втором правильный. в первом случае сервер не понимал что запрос закончен и соответственно не давал ответ

SlothSpot
()

Попробуй fork + exec("wget ...")

Absurd ★★★
()
Ответ на: комментарий от Spectr

Большое спасибо! Теперь понимаю, что я там не так делал.

trex6 ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.