2016-02-21 4 views
1

У меня есть приложение сокетов и вы хотите, чтобы браузеры могли отправлять/получать данные. К сожалению, по какой-то нечетной причине этот код просто не будет работать для Chrome, а не завиток. Странно, однако, похоже, что он отлично работает с Internet Explorer Edge и даже некоторыми игровыми площадками REST, доступными в Интернете.Правильная отправка ответа HTTP через сокеты

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

Что происходит, Chrome загружает данные, но киоски и официальный ответ так и не получили - или, может быть, это просто не закончилось? Я могу видеть весь текст на странице, однако Google по-прежнему загружается, а «Ответ сервера» сообщает, что он ничего не получил. В дополнение к этому, я думаю, что он посылает один и тот же ответ клиенту дважды.

Вот мой код:

// sockserver.cpp : Defines the entry point for the console application. 
// 

#define WIN32_LEAN_AND_MEAN 
#include <winsock2.h> 
#include <process.h> 
#include <stdio.h> 
#include <map> 
#pragma comment(lib,"ws2_32.lib") 

unsigned int __stdcall ServClient(void *data); 

int main(int argc, char* argv[]) 
{ 

    WSADATA wsaData; 
    int iResult; 
    sockaddr_in addr; 
    SOCKET sock, client; 

    addr.sin_family = AF_INET; 
    addr.sin_port = htons(5900); 
    addr.sin_addr.S_un.S_addr = inet_addr("192.168.0.22"); 

    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);//2.2 

    if (iResult) 
    { 
     printf("WSA startup failed"); 
     return 0; 
    } 


    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 

    if (sock == INVALID_SOCKET) 
    { 
     printf("Invalid socket"); 
     return 0; 
    } 

    iResult = bind(sock, (sockaddr*)&addr, sizeof(sockaddr_in)); 

    if (iResult) 
    { 

     printf("bind failed %u", GetLastError()); 

     return 0; 
    } 

    iResult = listen(sock, SOMAXCONN); 

    if (iResult) 
    { 

     printf("iResult failed %u", GetLastError()); 

     return 0; 
    } 

    while (client = accept(sock, 0, 0)) 
    { 
     if (client == INVALID_SOCKET) 
     { 
      printf("invalid client socket", GetLastError()); 
      continue; 
     } 
     _beginthreadex(0, 0, ServClient, (void*)&client, 0, 0); 

    } 


    return 0; 
} 

std::map<int, SOCKET> sockList; 
unsigned int __stdcall ServClient(void *data) 
{ 
    SOCKET* client = (SOCKET*)data; 
    SOCKET Client = *client; 
    printf("Client connected\n"); 

    int xx = 0; 

    char chunk[200]; 
    while (recv(Client, chunk, 200, 0)) 
    { 

     char buf[] = "HTTP/1.1 200 OK\nContent-Type: text/html\nAccept: */*;Date:Sun, 21 Feb 2016 18:26:33 GMT\nServer: ubersnip\nContent-Length:18076\nAccept-Encoding:gzip, deflate, sdch\nAccept-Language:en-US,en;q=0.8\nCache-Control:max-age=0\nConnection:keep-alive\nHost:localhost:2222\nSet-Cookie:acct=t=t%2flE8KL9jDBOed05o1eMDiINlDfMvLxp&s=CUBOpXFMXmBt4u3pf%2fx5efr5WWkyGT3U; domain=.stackoverflow.com; expires=Sun, 21-Aug-2016 18:26:33 GMT; path=/; HttpOnly\n\n<html><body>Hello World</body></html>"; 

     //sockList[sockList.size()] = Client; 
     send(Client, buf, strlen(buf), 0); 
     /*if (xx >= 1) { 
      closesocket(Client); 
      return 1; 
     } 
     else { 
      xx++; 
     }*/ 
     printf("%s \t %d\n", chunk, GetCurrentThreadId()); 
    } 
    return 0; 
} 
+0

Я думаю, что нужно удалить тег google-chrome из вопроса. – oklas

ответ

1

Вы настраиваете огромный Content-длина 18076, но ваше содержание гораздо гораздо меньше. Таким образом, браузер будет ожидать большего количества контента. Но вместо предоставления большего количества контента вы просто ждете, пока браузер отправит другой запрос, и поэтому клиент и сервер ждут друг друга.

Кроме того, у вас есть много заголовков, которые вы отправляете, не имеют смысла: Accept, Encoding, Accept-Language и Host - все заголовки, которые имеют отношение к запросу и не имеют смысла в ответе. И правильная строка, заканчивающаяся HTTP, равна \r\n, а не \n, хотя браузеру обычно не нужна эта деталь.

+0

А теперь это тоны смысла! : D Итак, как определить длину содержимого? Является ли это количеством символов, а также должно включать заголовки? – user2292759

+0

@ user2292759: Длина содержимого - это длина всего тела, в октетах (байтах), а не в (возможно многобайтовых) символах. –

+0

Спасибо! Прекрасно работает! Что-то мне подсказывало, что это были заголовки. Огромное спасибо! : D – user2292759

1

То, что кажется, так это Chrome загружает данные, но, киосков

Как вы упоминали «киосков», глядя на ваш код, вы звоните «ПРИЕМ», который является блокирующий вызов. Если данных нет, recv будет блокироваться.

Возможно ли это, если вы остановитесь? Существуют API-интерфейсы, доступные для проверки наличия первых данных, чтобы избежать блокировки. Просто упомянуть об этом, он помогает.

Если вы добрались до «send()», я сомневаюсь, что вы остановитесь, но это тоже возможно.

+0

Спасибо за это! Нагружается намного быстрее теперь .... Не совсем уверен, почему я использовал, а :) Оценил! PS: Я ДУМАЮ, что также исправил двойную отправку;) – user2292759

+0

У меня есть вопрос в отношении этого, хотя, и я думаю, именно поэтому я и использовал. Если один и тот же клиент повторно передает данные, как я могу расшифровать, какой клиент он отправил данные ... С течением времени нить никогда не закрывалась, поэтому мне удалось получить данные и провести различие между клиентами. Предложения? – user2292759

Смежные вопросы