html - 如何用C语言控制Web服务器和客户端之间的框架交换?

标签 html c sockets webserver tcp

我是一名编程新手,我的任务是编写一个基于 WIZnet w5200 的网络服务器。
我开发了控制和生成套接字的所有功能,但现在我需要打印一个仅包含少量数据的网页。 事实上,他们将是一台通过以太网线连接到 WIZnet 的 PC,我想要做的是在这台 PC 上使用 Internet Explorer 打开一个网页。 例如,我在 Wireshark 上得到一些奇怪的框架,在我的 Internet Explorer 屏幕上得到“HHHHHHHHHHHHHHHH...等”(编辑-->不再有奇怪的框架或多个“H”)。我开发了动态创建 html 代码的函数。 这是我的代码的一部分,告诉我是否有什么令人窒息的(除了它很奇怪的事实):

switch(Get_S0_SR())
 {
    case SOCK_ESTABLISHED:
         printf("\n\n  establish  \n\n");
         /*if(Get_S0_RX_RSR()!=0)                 //on regarde si on a reçu des data
         {
             printf("\n\nsize recv = %x\n\n",Get_S0_RX_RSR());
             recv_data=recv_Socket();         //si oui on procède à la reception de ces données

         }*/
         //if(analog_data!=0)                     //on regarde si on as une donnée analogique
         //{
             printf("\n\ndeuxieme\n\n");
             val=0;
             while(val!=1)
             {
                val=send_Socket();//on envoi cette donnée via ethernet
                printf("\n\nFINI\n\n");
             }

         //}
         //else
         //{
            //goto SOCK_CLOSE_WAIT;
            disconnect_Socket();
            printf("\n\ndisconnect\n\n");
         //}
         break; 

    case SOCK_CLOSE_WAIT:
         printf("\n\nSOCK_CLOSE_WAIT\n\n");
         if(Get_S0_RX_RSR()!=0)               //on regarde si on a reçu des data
         {
             recv_data=recv_Socket();         //si oui on procède à la reception de ces données
             disconnect_Socket();             //une fois le processus finis on se deconnecte
             //goto SOCK_CLOSED;
         }
         if(Get_S0_IR()==S0_IR_TIMEOUT)
         {
             //goto SOCK_CLOSED;
             disconnect_Socket();
         }
         else
         {   
             //goto SOCK_ESTABLISHED;
             disconnect_Socket();
         }
         break;  

    case SOCK_CLOSED:
         printf("\n\nSOCK_CLOSE\n\n");
         close_Socket();
         break;

    case SOCK_INIT:
         val=listen_Socket();
         while(Get_S0_SR()!=SOCK_ESTABLISHED)
         {
            printf("\n\non attend la connection\n\n");
            //delay(1000);
         }
         printf("\n\nstatu=%x\n\n",Get_S0_SR());
         delay(1000);
        break;
    default:
        break;
}
//printf("\n\nstatu=%x\n\n",Get_S0_SR());
return ;

}

还有一个更新:

我使用 strcpy() 用 html 填充缓冲区(如底部代码所示),然后得到我想要的网页(“tracabilite[]”中包含的数据除外)。唯一的问题是我多次显示同一段!就像我之前的“HHHHHHHHHH...etc”问题一样。我认为它来自 WIZnet 的传输缓冲区。它的大小是否应该按照 HTTP 帧的确切长度进行初始化? 我试图弄清楚,但例如我没有。

这是生成 html 的新代码:

   unsigned short debut_trame(void)
{
  //unsigned char idx;
  unsigned short taille;
  //on vas stocker notre chaine de caractère html grace à strcpy
  strcpy(Write_Com_WIZnet,"HTTP/1.1 200 OK\rContent-Type:Text/html; 
<charset=utf-8>\r\n<!DOCTYPE html>\n<html>\n<body>\n<h1>Donnees de soudure</h1><p>"); 
  taille=strlen("HTTP/1.1 200 OK\rContent-Type:Text/html; <charset=utf-
8>\r\n<!DOCTYPE html>\n<html>\n<body>\n<h1>Donnees de soudure</h1><p>");
  printf("\ntaille trame=%d",taille);
  //on vas écrire cette chaine de caractère dans le buffer TX   
  write_WIZnet(0x8000,taille);
  return taille;
}

unsigned short liste_analog_data(unsigned short taille)
{
  unsigned short len;
  strcpy(Write_Com_WIZnet,"Puissance_Alim=");
  len=strlen("Puissance_Alim=");
  Write_Com_WIZnet[len]=tracabilite[0];
  Write_Com_WIZnet[len+1]=tracabilite[1];
  strcpy((Write_Com_WIZnet+(len+2)),"<br />");
  len+=strlen("<br />")+2;
  strcpy((Write_Com_WIZnet+(len)),"Courant_Alim=");
  len+=strlen("Courant_Alim=");
  Write_Com_WIZnet[len]=tracabilite[2];
  Write_Com_WIZnet[len+1]=tracabilite[3];
  strcpy((Write_Com_WIZnet+(len+2)),"<br />");
  len+=strlen("<br />")+2;
  strcpy((Write_Com_WIZnet+(len)),"Tension_Alim=");
  len+=strlen("Tension_Alim=");
  Write_Com_WIZnet[len]=tracabilite[4];
  Write_Com_WIZnet[len+1]=tracabilite[5];
  strcpy((Write_Com_WIZnet+(len+2)),"<br />");
  len+=strlen("<br />")+2;
  strcpy((Write_Com_WIZnet+(len)),"Courant_Generateur=");
  len+=strlen("Courant_Generateur=");
  Write_Com_WIZnet[len]=tracabilite[6];
  Write_Com_WIZnet[len+1]=tracabilite[7];
  strcpy((Write_Com_WIZnet+(len+2)),"<br />");
  len+=strlen("<br />")+2;
  strcpy((Write_Com_WIZnet+(len)),"Frequence=");
  len+=strlen("Frequence=");
  Write_Com_WIZnet[len]=tracabilite[8];
  Write_Com_WIZnet[len+1]=tracabilite[9];
  strcpy((Write_Com_WIZnet+(len+2)),"<br />");
  len+=strlen("<br />")+2;
  strcpy((Write_Com_WIZnet+(len)),"Temps_Soudure=");
  len+=strlen("Temps_Soudure=");
  Write_Com_WIZnet[len]=tracabilite[10];
  Write_Com_WIZnet[len+1]=tracabilite[11];
  strcpy((Write_Com_WIZnet+(len+2)),"<br />");
  len+=strlen("<br />")+2;
  strcpy((Write_Com_WIZnet+(len)),"Statut=");
  len+=strlen("Statut=");
  Write_Com_WIZnet[len]=tracabilite[12];
  Write_Com_WIZnet[len+1]=tracabilite[13];
  strcpy((Write_Com_WIZnet+(len+2)),"<br />");
  len+=strlen("<br />")+2;
  strcpy((Write_Com_WIZnet+(len)),"SWR=");
  len+=strlen("SWR=");
  Write_Com_WIZnet[len]=tracabilite[14];
  Write_Com_WIZnet[len+1]=tracabilite[15];
  strcpy((Write_Com_WIZnet+(len+2)),"<br />");
  len+=strlen("<br />")+2;
  strcpy((Write_Com_WIZnet+(len)),"</p>\n</body>\n</html>\0");
  len+=strlen("</p>\n</body>\n</html>\0");
  write_WIZnet(0x8000+taille,len);
  taille+=len;
  return taille;
}


void genere_HTML(void)
{
  unsigned short size, size2;
  printf("\non genere la page\n");
  size=debut_trame();
  size2=liste_analog_data(size);
  //size2+=size;
  printf("\nenvoi de la page au WIZnet, taille=%x\n",size2);
  //write_WIZnet(0x8000,size2);
}

我知道它很丑,但它正在工作(至少在外观上)...问题是我多次显示它。 任何有关 HTTP、HTML 或其他内容的帮助都会很有用!

最佳答案

这并不是一个真正的答案,但评论太多了。 我还清理了一些与提供示例文件相关的评论。

使用更改后的创建 HTML 内容的函数,可以正确复制文本。

但是查看 Wireshark 文件的第 8 帧,您可以看到 HTTP 数据并非以您准备的内容开始,也不是从字节 #0 开始。相反,它开始得晚得多。 帧的 HTTP 数据部分从偏移量 0x36 开始。您的文本从偏移量 0x220 处可见。 我不知道你可以在哪里配置哪个缓冲区用作 TCP 连接的内容,但你在这里偏离了 490 字节。

另一个问题是可见的。如果您查看 TCP 流,您可以看到传输的数据约为 40KiB,这太多了。

在内容中,您可以发现准备好的内容的多个副本,但只有 1 个 GET 请求。

从你的函数中我可以看到一些新问题:

unsigned char* genere_HTML(void)
{
  unsigned char* return_strcpy;
  strcpy(Write_Com_WIZnet,"HTTP/1.1 200 OK\nContent-Type:Text/html; 
  charset=utf-8\n\n<html>\n<body>\n<h1>\n1 2 3 4\n</h1>\n</body>\n</html>");
  write_WIZnet(0x8000,200);
  return return_strcpy;
}

这里返回return_strcpy未初始化的内容。无论对该函数的返回值做什么,都没有任何好处。

您还可以使用 write_WIZnet 的硬编码参数。没有关于内容长度或存储位置的提示。 假设隐式使用 Write_Com_WIZnet,您仍然没有长度信息。

我也不知道这些值的含义。

无论您的缓冲区传输到哪里,问题都不在这个问题中可见的部分。

关于html - 如何用C语言控制Web服务器和客户端之间的框架交换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44307467/

相关文章:

c - 输入缓冲区获取输入,C 编程

c - 1,2,1,3,2,5,3,7,5,11,8,13,13,17... 打印第 N 项

c++ - async_resolve 中的 boost::asio::ip::tcp::resolver::iterator 的生命周期是多少?

c# - EndRead引发IO异常

html - 为每个要打印的页面设置边距/填充(html/css)?

html - 单击表格单元格上的 Angular 2 使其可编辑

html - CSS:div 内元素的动态宽度

c++ - 位运算 OR 与加法

python - 无需端口转发的点对点套接字通信

javascript - <select> 选项无需 AJAX 即可更改