Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Пример работы с сокетами (socket) для Windows

© Mikhail Krivyy
19 декабря 2002 года

Писал, когда сам разбирался с этим делом. На базе этого простого примера написано (точнее не совсем на его базе, а скорее при его участии) пара серьезных программок.

Все просто, как в танке. По исходникам разберетесь.

socket.cpp

Код:
#include <windows.h>

#include <stdio.h>
#include <string.h>

char* OpenURL(char *url) {
    WSADATA lpWSAData;
    SOCKET s;

    // Проверим на правильность введенный адрес.
    // Он должен начинаться с "http://"
    if (memcmp(url,"HTTP://",7)!=0 && memcmp(url,"http://",7)!=0) return(NULL);
    url+=7;

    // Инициализация библиотеки Ws2_32.dll.
    if (WSAStartup(MAKEWORD(1,1),&lpWSAData)!=0) return(NULL);


    // Получим имя хоста, номер порта и путь ----------------------------

    char *http_host=strdup(url); // Имя хоста (HTTP_HOST)
    int port_num=80;             // Номер порта по умолчанию (HTTP_PORT)
    char *http_path=NULL;        // Путь (REQUEST_URI)

    char *pch=strchr(http_host,':');
    if (!pch) {
        pch=strchr(http_host,'/');
        if (pch) {
            *pch=0;
            http_path=strdup(pch+1);
            }
        else http_path=strdup("");
        }
    else {
        *pch=0;pch++;
        char *pch1 = strchr(pch,'/');
        if (pch1) {
            *pch1=0;
            http_path=strdup(pch1+1);
            }
        else http_path=strdup("");

        port_num = atoi(pch);

        if (port_num==0) port_num = 80;
        }

    // Поучаем IP адрес по имени хоста
    struct hostent* hp;
    if (!(hp=gethostbyname(http_host))) {
        free(http_host);
        free(http_path);
        return(NULL);
        }

    // Открываем сокет
    s=socket(AF_INET, SOCK_STREAM, 0);
    if (s==INVALID_SOCKET) {
        free(http_host);
        free(http_path);
        return(NULL);
        }

    // Заполняем структуру sockaddr_in
    struct sockaddr_in ssin;
    memset ((char *)&ssin, 0, sizeof(ssin));
    ssin.sin_family = AF_INET;
    ssin.sin_addr.S_un.S_un_b.s_b1 = hp->h_addr[0];
    ssin.sin_addr.S_un.S_un_b.s_b2 = hp->h_addr[1];
    ssin.sin_addr.S_un.S_un_b.s_b3 = hp->h_addr[2];
    ssin.sin_addr.S_un.S_un_b.s_b4 = hp->h_addr[3];
    ssin.sin_port = htons(port_num);

    // Выводим IP адрес хоста, с которым будем соединятся
    printf("Conecting to %d.%d.%d.%d...",(unsigned char)hp->h_addr[0],
                                         (unsigned char)hp->h_addr[1],
                                         (unsigned char)hp->h_addr[2],
                                         (unsigned char)hp->h_addr[3]);

    // Соединяемся с хостом
    if (connect(s, (sockaddr *)&ssin, sizeof(ssin))==-1) {
        free(http_host);
        free(http_path);
        printf("Error\n");
        return(NULL);
        }
    printf("Ok\n");

    // Формируем HTTP запрос
    char *query=(char*)malloc(2048);

    strcpy(query,"GET /");
    strcat(query,http_path);
    strcat(query," HTTP/1.0\nHost: ");
    strcat(query,http_host);
    strcat(query,"\nUser-agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
    strcat(query,"\nAccept: */*\n\n");


    // Выводим HTTP запрос
    printf("%s",query);

    // Отправляем запрос серверу
    int cnt=send(s,query,strlen(query),0);

    // Освобождаем память
    free(http_host);
    free(http_path);
    free(query);

    // Проверяем, не произошло ли ошибки при отправке запроса на сервер
     if (cnt==SOCKET_ERROR) return(NULL);

    cnt=1;

    // Получаем ответ с сервера ---------------------------------

    int size=1024*1024; // 1Mb
    char *result=(char*)malloc(size);
    strcpy(result,"");
    char *result_ptr=result;

    while (cnt!=0 && size>0) {
        cnt=recv (s, result_ptr, sizeof(size),0);
        if (cnt>0) {
            result_ptr+=cnt;
            size-=cnt;
            }
        }
    *result_ptr=0;

    // Деинициализация библиотеки Ws2_32.dll
    WSACleanup();

    return(result);
    }

void main(void) {
    char *result=OpenURL("http://www.codenet.ru/");
    if (result) {
        printf("%s",result);
        free(result);
        }
    else {
        printf("Error # WSABASEERR+%d\n",WSAGetLastError()-WSABASEERR);
        }
    }

Оставить комментарий

Комментарий:
можно использовать BB-коды
Максимальная длина комментария - 4000 символов.
 

Комментарии

1.
96K
15 ноября 2015 года
Татьяна Шевченко
0 / / 15.11.2015
Мне нравитсяМне не нравится
15 ноября 2015, 00:47:51
Чтобы на студии 2012 заработало, пришлось заменить #include <windows.h> на #include <winsock2.h> #include <ws2tcpip.h>.

Спасибо за полезную программу!
2.
37K
08 февраля 2008 года
K@STET
0 / / 08.02.2008
Мне нравитсяМне не нравится
8 февраля 2008, 17:36:34
Кто-нибудь обясните пожалуста все по порядку.
Что мне нужно создавать Проект или Просто срр-шку? Куда кидать листинг?
Буду очень признателен. Это надо для курсача
3.
Аноним
+0 / -1
Мне нравитсяМне не нравится
12 марта 2006, 20:25:17
to Freddy:
вместо BOOL OpenURL(char *host_name)
ты наверно хотел написать BOOL OpenURL(char *url)

а вообще, не хорошо примеры с ошибками постить
4.
Аноним
Мне нравитсяМне не нравится
23 февраля 2006, 11:45:05
./http_connect.c
#include "http_connect.h"
static char Rec[2048000];
WSADATA wsaData;
long GetString(SOCKET s)
{
char *str;
char InBuff[2048];
int cnt;
long bytes =0;
while (cnt!=0)
{
memset(&InBuff,0,2048);
cnt = recv (s, (char*)&InBuff, sizeof(InBuff),0);
bytes =bytes +cnt;
strcat(Rec,InBuff);
}
return bytes;
}
BOOL SendString(SOCKET s,char* str)
{
int cnt = send(s,str,strlen(str),0);
if (cnt == SOCKET_ERROR)
return FALSE;
else
return TRUE;
}
BOOL OpenURL(char *host_name)
{
SOCKET s;
char *none="";
int PortNum;
struct sockaddr_in ssin;
struct hostent* hp;
char strHlp[2048], *pch;
char query[2048];
char *http_path;
char *http_host;
if (!memcmp(url,"HTTP://",7))
return 7;
url+=7;
strcpy(strHlp,url);
pch = strchr((char*)strHlp,':');
if (pch==NULL)
PortNum = 80;
else
{
pch[0] = '\0';
PortNum = atoi(++pch);
if(PortNum == 0)
PortNum = 80;
}
pch = strchr((char*)strHlp,'/');
if (pch!=NULL)
{
pch[0] = '\0';
http_path=pch+1;
}
else
{
http_path=none;
}
if ((hp = gethostbyname(strHlp)) == NULL)
return(1);
http_host = strHlp;
memset ((char *)&ssin, 0, sizeof(ssin));
ssin.sin_family = AF_INET;
ssin.sin_addr.s_addr = htonl(INADDR_ANY);
ssin.sin_port = 0;
s = socket(AF_INET, SOCK_STREAM, 0);
if (s==INVALID_SOCKET)
return 4;
ssin.sin_family = AF_INET;
ssin.sin_addr.S_un.S_un_b.s_b1 = hp->h_addr[0];
ssin.sin_addr.S_un.S_un_b.s_b2 = hp->h_addr[1];
ssin.sin_addr.S_un.S_un_b.s_b3 = hp->h_addr[2];
ssin.sin_addr.S_un.S_un_b.s_b4 = hp->h_addr[3];
ssin.sin_port = htons(PortNum);
sprintf(Rec, "Conecting to %d.%d.%d.%d...",
(unsigned char)hp->h_addr[0],
(unsigned char)hp->h_addr[1],
(unsigned char)hp->h_addr[2],
(unsigned char)hp->h_addr[3]);
if (connect(s, (struct sockaddr *)&ssin, sizeof(ssin)) == -1)
return 3;
strcat(Rec, "OK\n");
strcpy(query,"GET /");
strcat(query,http_path);
strcat(query," HTTP/1.0\nHost: ");
strcat(query,http_host);
strcat(query,"\nUser-agent: ");
strcat(query,"http_user_agent");
strcat(query,"\nAccept: */*\n\n");
strcat(Rec, query);
if (!SendString(s,query))
return 5;
char result[512];
xsprintf(result, "Bytes receved: %d", GetString(s));
strcat(Rec,result);
return 0;
}
static BOOL CALLBACK DialogFunc(
HWND hwndDlg,
UINT msg,
WPARAM wParam,
LPARAM lParam)
{
char host_name[MAX_PATH];
BYTE error;
switch (msg)
{
case WM_INITDIALOG:
if (WSAStartup(MAKEWORD(1,1),&wsaData))
return 0;
return 1;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_URL_CONNECT:
GetDlgItemText(hwndDlg, IDC_URL_HOST, host_name, MAX_PATH);
if ((error =OpenURL(host_name)) !=0)
{
sprintf(Rec, "Error #%d: WSABASEERR+%d\n",error,
WSAGetLastError()-WSABASEERR);
}
WSACleanup();
SetDlgItemText(hwndDlg, IDC_EDIT, Rec);
break;
} //2
break;
} //1
return 0;
}
int APIENTRY WinMain
(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow
)
{
WNDCLASS wc;
memset(&wc,0,sizeof(wc));
wc.lpfnWndProc = DefDlgProc;
wc.cbWndExtra = DLGWINDOWEXTRA;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon =NULL;
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
wc.lpszClassName = "urlconnect";
if (!RegisterClass(&wc))
return 0;
return DialogBox
(
hInstance,
MAKEINTRESOURCE(IDD_DIALOG),
NULL,
(DLGPROC) DialogFunc);
}
./http_connect.h
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <string.h>
#include <winsock.h>
#include <stdio.h>
// definition
#define IDD_DIALOG 1000
#define IDC_URL_HOST 1001
#define IDC_URL_CONNECT 1002
#define IDC_EDIT 1003
5.
Аноним
Мне нравитсяМне не нравится
15 февраля 2006, 16:26:47
Спасибо, очень содержательный пример. А то без MSDN как-то тяжеловато шло.
6.
Аноним
Мне нравитсяМне не нравится
23 января 2006, 14:10:50
ой не.. гоню я :) действительно нафиг биндить сокет?
7.
Аноним
Мне нравитсяМне не нравится
23 января 2006, 13:43:35
2 илья оконский

если внимательно посмотришь исходный текст, то увидишь, что там еще и получают данные, а не только отправляют....
cnt=recv (s, result_ptr, sizeof(size),0);
8.
Аноним
+0 / -1
Мне нравитсяМне не нравится
22 января 2006, 19:18:13
iAlexander
Аффтар ЖжжоТТ ==). Это называеЦЦа комментарии? Хы =) краткость сестра таланТа =). еще бы на иврите комментировал =).
9.
Аноним
Мне нравитсяМне не нравится
14 января 2006, 18:34:25
Да, отличная программа, я сейчас под юних пишу очень помог список параметров пост запросов.
Кстати, может кто знает как проще чат написать в консоли
10.
Аноним
Мне нравитсяМне не нравится
1 января 2006, 15:20:32
Очень интересная строчка :)...
bind (s, (struct sockaddr *)&ssin, sizeof(ssin));
Зачем она тебе нужна??? это ж у тебя
клиентский сокет! Да ищё нахрена тебе это надо до объявления сокета???
Сразу видно, что криво писано, и код передёртый... Просто ужас!!!!!!1
Аффтар выпей йаду!!!
11.
Аноним
Мне нравитсяМне не нравится
4 апреля 2005, 14:06:45
Ну хоть бы коментарии добаваил а то читаешь как "Отче Наш". Люди это учебный материал или "грузящий" ???
Ну хоть так...
12.
Аноним
Мне нравитсяМне не нравится
15 марта 2005, 14:29:47
Соединится получится. Прокси серверу нужно отправить логин и пароль. Почитай про HTTP протокол, там все написано.
13.
Аноним
Мне нравитсяМне не нравится
15 марта 2005, 13:16:33
А как же соединяться с помощью сокетов при наличии обязательной авторизацией на прокси-сервере? Данный код не пройдет прокси, а следовательно не будет и работать.
14.
Аноним
+1 / -0
Мне нравитсяМне не нравится
3 сентября 2004, 16:58:11
Пишу, пока сам разбираюсь с этим делом.
Смотрите чуть модифицированный и прокомментированный код.
От себя хочу добавить, что когда будете компилировать, не забудьте присоединить к проекту WSOCK32.LIB, иначе будет куча unresolved symbols

socket.cpp

Код:
#include "stdio.h"

#include "socket.h"

#include "config.h"



static char Rec[2048000];

//

// routine for send request in 'str' to socket in 's'

//

bool SendString(SOCKET s,char* str)

{

    int cnt = send(s,str,strlen(str),0);

    if (cnt == SOCKET_ERROR) return(false); else return(true);

}



//

// routine for receive entire information from 's'

// socket and store it in 'Rec' buffer

//

char* GetString(SOCKET s)

{

    char *str;

    char InBuff[2048];

    int cnt;

   

    strcpy("",Rec);

    while (cnt!=0) {

        // clear InBuff - fill 2048 bytes to NULL

        memset(&InBuff,0,2048);

        // receive a 2048 bytes from 's' sock

        cnt = recv (s, (char*)&InBuff, sizeof(InBuff),0);  

        // append it to main buffer 'Rec'

        strcat(Rec,InBuff);

    }

    return((char*)&Rec);

}





//

// routine to

//

int OpenURL(char *url) {

    // empty string

    char *none="";                         

    // string for send request to server

    char query[2048];

    struct sockaddr_in ssin;

    struct hostent* hp;

    char strHlp[2048], *pch;

    int PortNum;

    char *http_host;

    char *http_path;



    // ensure that url starts with "HTTP://" or "http://"

    if (memcmp(url,"HTTP://",7)!=0 && memcmp(url,"http://",7)!=0)

        return(7);

    url+=7; // seek "http://"

    // initialize structure WSADATA lpWSAData defined in 'socket.h'

    if (WSAStartup(MAKEWORD(1,1),&lpWSAData)!=0)

        return(1);

    // use default port number - 80 if not specified other

    // strHlp - helper string that contains server name and path on the server

    strcpy(strHlp,url);                    

    pch = strchr((char*)strHlp,':');

    // port not defined in passed URL

    if (pch==NULL) {   

        PortNum = 80;

    }

    // port defined in passed URL

    else {     

        pch[0] = '\0';  // truncate port from URL

        PortNum = atoi(++pch);

        if(PortNum == 0) PortNum = 80;

    }



    // separate server name from path on server

    pch = strchr((char*)strHlp,'/');

    if (pch!=NULL) {

        pch[0] = '\0';

        http_path=pch+1;

    }

    else {

        http_path=none;

    }



    // Get Host IP by Host name

    if ((hp = gethostbyname(strHlp)) == NULL)

            return(1);

    http_host = strHlp;



    // clear sockaddr_in ssin structure

    memset ((char *)&ssin, 0, sizeof(ssin));           

    ssin.sin_family = AF_INET;

    ssin.sin_addr.s_addr = htonl(INADDR_ANY);

    ssin.sin_port = 0;

    // associate ssin with a  socket 's'

    bind (s, (struct sockaddr *)&ssin, sizeof(ssin));  



    s = socket(AF_INET, SOCK_STREAM, 0);

    if (s==INVALID_SOCKET) return(4);



    ssin.sin_family = AF_INET;

    ssin.sin_addr.S_un.S_un_b.s_b1 = hp->h_addr[0];

    ssin.sin_addr.S_un.S_un_b.s_b2 = hp->h_addr[1];

    ssin.sin_addr.S_un.S_un_b.s_b3 = hp->h_addr[2];

    ssin.sin_addr.S_un.S_un_b.s_b4 = hp->h_addr[3];

    ssin.sin_port = htons(PortNum);



    printf("Conecting to %d.%d.%d.%d...",

        (unsigned char)hp->h_addr[0],

        (unsigned char)hp->h_addr[1],

        (unsigned char)hp->h_addr[2],

        (unsigned char)hp->h_addr[3]);

    // establish a connection with socket 's'

    if (connect(s, (sockaddr *)&ssin, sizeof(ssin)) == -1)

        return(3);

    printf("Ok\n");



    strcpy(query,"GET /");

    strcat(query,http_path);

    strcat(query," HTTP/1.0\nHost: ");

    strcat(query,http_host);

    strcat(query,"\nUser-agent: ");

    strcat(query,http_user_agent);

    strcat(query,"\nAccept: */*\n\n");



    printf("%s",query);



    // send request

    if (!SendString(s,query)) return(5);

    // receive response

    char* str = GetString(s);

    printf("%s",str);

    return(0);

    }



void CloseURL(void) {

    WSACleanup();

}

                         

void main(void)

{              

    int err=OpenURL("http://www.codenet.ru/");

    if (err != 0) {

        printf("Error #%d: WSABASEERR+%d\n",err,

        WSAGetLastError()-WSABASEERR);

    }

    CloseURL();

}
15.
Аноним
+0 / -1
Мне нравитсяМне не нравится
17 августа 2004, 23:04:51
нифига не понял, будь другом, прокомментируй все или хотя бы основы !!
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог