29447945 发表于 2020-8-31 19:35

【树莓派4B测评】+TCP服务器和HTTP通信

<div class='showpostmsg'><p>今天使用树莓派搭建一个TCP服务器,使用HTTP通信,话不多说,直接开始;</p>

<p>首先检查树莓派是都安装curl库;</p>

<p>输入命令:curl www.baidu.com</p>

<p>可以看到是有curl库的,如果没有也可以自己装一下;</p>

<p>然后就是建立TCP服务,通过socket通信完成;具体过程:建立socket-&gt;绑定端口和IP-&gt;Listen-&gt;等待客户端连接-&gt;断开连接;如果是客户端则是:建立socket-&gt;绑定端口和IP-&gt;连接服务器-&gt;断开连接;</p>

<p>代码如下:</p>

<pre>
<code class="language-cpp">int main(int argc,char **argv)
{
    const int port = 9689;//listen port
    int listenfd=Socket(AF_INET,SOCK_STREAM,0);

    struct sockaddr_in serverAddr;
    serverAddr.sin_family=AF_INET;
    serverAddr.sin_addr.s_addr=INADDR_ANY;
    serverAddr.sin_port=htons(port);
    Bind(listenfd,(struct sockaddr*)&amp;serverAddr,sizeof(serverAddr));
    Listen(listenfd,5);

    while(true)
    {
      handleAccept(listenfd);
    }

}

int Socket(int family , int type,int protocol)
{
    int   n;
    if ( (n = socket(family, type, protocol)) &lt; 0)
    {
      printf("socket error\r\n");
      return -1;
    }
    return(n);

}
void
Bind(int fd, const struct sockaddr *sa, socklen_t salen)
{
    if (bind(fd, sa, salen) &lt; 0)
    {
      printf("bind error\r\n");
      exit(-1);
    }
}
void
Listen(int fd, int backlog)
{
    char    *ptr;

      /*4can override 2nd argument with environment variable */
    if ( (ptr = getenv("LISTENQ")) != NULL)
      backlog = atoi(ptr);

    if (listen(fd, backlog) &lt; 0)
    {
      printf("listen error\r\n");
      return ;
    }
}
int
Accept(int fd, struct sockaddr *sa, socklen_t *salenptr)
{
    int   n;

again:
    if ( (n = accept(fd, sa, salenptr)) &lt; 0) {
#ifdefEPROTO
      if (errno == EPROTO || errno == ECONNABORTED)
#else
      if (errno == ECONNABORTED)
#endif
            goto again;
      else
      {
            printf("accept error\r\n");
            return -1;
      }
    }
    return(n);
}

void handleAccept(int listenfd)
{
    sockaddr_in clientAddr;
    socklen_t clientLen=sizeof(clientAddr);
    int connfd=Accept(listenfd,(sockaddr *)&amp;clientAddr,&amp;clientLen);
    handleHttp(connfd);
    close(connfd);
}
</code></pre>

<p>我这里做了一个简单的http例程,就是访问连接服务器后,回复一个网页,代码如下:</p>

<pre>
<code>void handleHttp(int connfd)
{
    if(getRequest(connfd)&lt;0)
    {
      perror("http request get error");
      exit(-1);
    }
}

int getRequest(int socket)
{
    int msgLen=0;
    char send_data;
    char buffer;
    memset (buffer,'\0', BUFFER_SIZE);
    if ((msgLen = recv(socket, buffer, BUFFER_SIZE, 0)) == -1)
    {
      printf("Error handling incoming request");
      return -1;
    }
    else
    {
      printf("recv:\n%s\n",buffer);
      

    }

    memset (send_data,'\0', BUFFER_SIZE);
    //create_objects(send_data);
   
    stringstream ss;
    ss&lt;&lt;buffer;
    string method;
    ss&gt;&gt;method;
    string uri;
    ss&gt;&gt;uri;
    string version;
    ss&gt;&gt;version;
   
    //
   
    string contentType("text/html");
    string content("&lt;html&gt;&lt;head&gt;&lt;title&gt;simple httpserver&lt;/title&gt;&lt;/head&gt;&lt;h1&gt;hello eeworld&lt;/h1&gt;&lt;/body&gt;&lt;/html&gt;");
    string contentSize(std::to_string(content.size()));

    string head("\r\nHTTP/1.1 ");
    string statusCode("200 OK");
    string ContentType("\r\nContent-Type: ");
    string ServerHead("\r\nServer: localhost");
    string ContentLength("\r\nContent-Length: ");
    string Date("\r\nDate: ");
    string Newline("\r\n");
    time_t rawtime;
    time(&amp;rawtime);
    string message;
    message+=head;
    message+=statusCode;
    message+=ContentType;
    message+=contentType;
    message+=ServerHead;
    message+=ContentLength;
    message+=contentSize;
    message+=Date;
    message+=(string)ctime(&amp;rawtime);
    message+=Newline;

    int messageLength=message.size();
    int n;
    n=send(socket,message.c_str(),messageLength,0);
    n=send(socket,content.c_str(),content.size(),0);   
    return n;
}</code></pre>

<p>然后编译一下:</p>

<p>g++ http_test.cpp -o http</p>

<p>在运行./http&nbsp;</p>

<p>服务运行后,我们用浏览器打开试下</p>

<p></p>

<p>打印了我们设置的内容;</p>

<p>我们在使用curl测试一下:</p>

<p>curl 192.168.31.235:9689</p>

<p></p>
</div><script>                                        var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;"   style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
                                       
                                        if(parseInt(discuz_uid)==0){
                                                                                                (function($){
                                                        var postHeight = getTextHeight(400);
                                                        $(".showpostmsg").html($(".showpostmsg").html());
                                                        $(".showpostmsg").after(loginstr);
                                                        $(".showpostmsg").css({height:postHeight,overflow:"hidden"});
                                                })(jQuery);
                                        }                </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>

freebsder 发表于 2020-9-7 19:59

<p>看到了最原始的CGI</p>
页: [1]
查看完整版本: 【树莓派4B测评】+TCP服务器和HTTP通信