博客
关于我
Linux套接子(c语言)模拟http请求、应答
阅读量:285 次
发布时间:2019-03-01

本文共 3085 字,大约阅读时间需要 10 分钟。

制作HTTP协议服务端代码与客户端代码

通过本地服务器实现简单的HTTP协议通信,能够帮助我们理解HTTP协议的工作原理。以下是基于C语言实现的HTTP协议服务端和客户端代码,以及相关的操作说明。

HTTP协议基础

HTTP协议是用于在分布式系统中传输网页内容的协议。其特点包括:

  • 无状态性:HTTP协议并不保留客户端和服务器之间的状态信息。
  • 可缓存性:服务器可以向客户端发送缓存指令,以减少数据传输量。
  • 可扩展性:HTTP协议支持通过扩展如HTTP/1.1版本实现更复杂的功能。
  • 服务端代码实现

    服务端代码基于以下思路:

  • 使用多线程处理客户端请求,提高服务器的吞吐量。
  • 接收客户端的HTTP请求,并返回预定义的响应内容。
  • 服务端代码示例

    #include 
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #define BUFFER_SIZE 1024#define NUM_THREADS 4void* thread.HandlerFunc(void* arg) { int client_socket = (int)arg; char http_response[2048] = "HTTP/1.1 200 OK\r\nContent-Length: 13\r\nConnection: close\r\n\hello world!\r\n"; // 接收客户端请求 char request[BUFFER_SIZE] = {0}; int n = read(client_socket, request, BUFFER_SIZE); printf("Client request: %s\n", request); // 发送响应 send(client_socket, http_response, strlen(http_response), 0); close(client_socket); printf("Client connection closed\n");}int main() { int server_socket; struct sockaddr_in server_addr; int opt = 1; // 创建套接子 server_socket = socket(AF_INET, SOCK_STREAM, 0); assert(server_socket != -1); // 设置服务器地址和端口 server_addr.sin_family = AF_INET; server_addr.sin_port = htons(80); // 使用80端口 server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 监听本地主机 // 绑定套接子 bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)); assert(bind == 0); // 开始监听 listen(server_socket, 5); // 最多同时接收5个连接请求 // 处理客户端连接 while (1) { int client_socket; struct sockaddr_in client_addr; int addr_len = sizeof(client_addr); // 接收客户端连接 client_socket = accept(server_socket, (struct sockaddr*)&client_addr, &addr_len); if (client_socket < 0) { continue; } // 启动一个新的线程处理客户端请求 pthread_t thread; pthread_create(&thread, NULL, thread.HandlerFunc, (void*)client_socket); } close(server_socket); return 0;}

    编译与运行

  • 编译
  • gcc -pthread -o server server.c
    1. 运行
    2. sudo ./server

      客户端代码示例

      #include 
      #include
      #include
      #include
      #include
      #include
      #include
      int main() { int client_socket; struct sockaddr_in server_addr; // 创建套接子 client_socket = socket(AF_INET, SOCK_STREAM, 0); assert(client_socket != -1); // 设置服务器地址和端口 server_addr.sin_family = AF_INET; server_addr.sin_port = htons(80); // 使用80端口 server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 服务器地址 // 连接到服务器 int result = connect(client_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)); assert(result != -1); // 发送HTTP请求 char request[1024] = "GET / HTTP/1.1\r\nHost: 127.0.0.1\r\nConnection: Close\r\n\r\n"; int bytes_sent = send(client_socket, request, strlen(request), 0); printf("Sent %d bytes\n", bytes_sent); // 接收服务器响应 char response[BUFFER_SIZE] = {0}; int bytes_received = recv(client_socket, response, BUFFER_SIZE, 0); printf("Received %d bytes\n", bytes_received); // 关闭套接子 close(client_socket); return 0;}

      使用说明

    3. 服务端

      • 监听本地127.0.0.1:80端口。
      • 使用多线程处理每个客户端请求。
      • 每次连接后自动关闭,服务器状态会在TIME_WAIT后继续监听。
    4. 客户端

      • 向本地服务器发送HTTP请求。
      • 接收服务器返回的HTTP响应。
      • 依次打印请求和响应内容。
    5. 通过以上代码,我们可以在本地机器上通过浏览器访问localhost,观察客户端与服务器之间的通信过程。

    转载地址:http://hoio.baihongyu.com/

    你可能感兴趣的文章
    Netty源码—5.Pipeline和Handler一
    查看>>
    Netty源码—5.Pipeline和Handler二
    查看>>
    Netty源码—6.ByteBuf原理一
    查看>>
    Netty源码—6.ByteBuf原理二
    查看>>
    Netty源码—7.ByteBuf原理三
    查看>>
    Netty源码—7.ByteBuf原理四
    查看>>
    Netty源码—8.编解码原理一
    查看>>
    Netty源码—8.编解码原理二
    查看>>
    Netty源码解读
    查看>>
    Netty的Socket编程详解-搭建服务端与客户端并进行数据传输
    查看>>
    Netty相关
    查看>>
    Netty遇到TCP发送缓冲区满了 写半包操作该如何处理
    查看>>
    Netty:ChannelPipeline和ChannelHandler为什么会鬼混在一起?
    查看>>
    Netty:原理架构解析
    查看>>
    Network Dissection:Quantifying Interpretability of Deep Visual Representations(深层视觉表征的量化解释)
    查看>>
    Network Sniffer and Connection Analyzer
    查看>>
    Network 灰鸽宝典【目录】
    查看>>
    NetworkX系列教程(11)-graph和其他数据格式转换
    查看>>
    Networkx读取军械调查-ITN综合传输网络?/读取GML文件
    查看>>
    network小学习
    查看>>