如何在C中控制Web服务器和客户端之间的框架交换?

时间:2017-06-01 12:23:52

标签: html c sockets webserver tcp-ip

我是编程新手,我的任务是基于WIZnet w5200编写网络服务器。
我开发了控制和生成套接字的所有功能,但现在我需要打印一个只包含少量数据的网页。 事实上,他们将是通过以太网线连接到WIZnet的PC,我想要做的就是在这台PC上打开带有Internet Explorer的网页。 例如,我在Wireshark上获得了一些奇怪的框架,在我的Internet Explorer屏幕上得到了“HHHHHHHHHHHHHHHHHH ......等”(编辑 - >不再是奇怪的框架或多个“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 ......等”问题一样。我认为它来自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或其他任何内容的帮助都是有用的!

1 个答案:

答案 0 :(得分:0)

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

使用更改的功能创建HTML内容,文本将被正确复制。

但是查看Wireshark文件的第8帧,您可以看到HTTP数据不是以您准备的内容开始,而是从字节#0开始。相反,它开始得晚得多。 帧的HTTP数据部分从偏移0x36开始。从偏移量0x220可以看到Yout文本。 我不知道在哪里可以配置哪个缓冲区用作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,您仍然没有长度信息。

我也没有任何关于这些价值观的信息。

无论您的缓冲区在何处传输,问题都不在此问题中可见的部分。