基于http传输(二)
来源:互联网 发布:手机工作证制作软件 编辑:程序博客网 时间:2024/04/28 19:39
文件传输
http传输的核心还是基于tcp/ip协议传输,服务器端启动,客户端通过指定的地址以及端口寻找服务器,然后进行连接;在windows下我们主要还是通过socket套接字建立连接:
/*服务器端*/WSAStartup(MAKEWORD(2, 0), &wsa_data); /* 初始化 WinSock 资源 */ srv_soc = socket(AF_INET, SOCK_STREAM, 0); /* 创建 socket */ if (srv_soc == INVALID_SOCKET) { printf("[Web] socket() Fails, error = %d\n", WSAGetLastError()); return -1; } /* 服务器地址 */ serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(port); serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); result = bind(srv_soc, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); if (result == SOCKET_ERROR) /* 绑定失败 */ { closesocket(srv_soc); printf("[Web] Fail to bind, error = %d\n", WSAGetLastError()); return -1; } result = listen(srv_soc, SOMAXCONN); printf("[Web] The server is running ... ...\n");
WSAStartup(MAKEWORD(2, 0), &wsa_data); /* 初始化 WinSock 资源 */ addr = inet_addr(host); if (addr == INADDR_NONE) { host_ent = gethostbyname(host); if (!host_ent) { printf("[Web] invalid host\n"); return -1; } memcpy(&addr, host_ent->h_addr_list[0], host_ent->h_length); } /* 客户端 */ serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(port); serv_addr.sin_addr.s_addr = addr; http_sock = socket(AF_INET, SOCK_STREAM, 0); /* 创建 socket */ result = connect(http_sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); if (result == SOCKET_ERROR) /* 连接失败 */ { closesocket(http_sock); printf("[Web] fail to connect, error = %d\n", WSAGetLastError()); return -1; }
紧接着client要发送http消息头让服务器处理:
/* 发送 HTTP 请求 */ send_len = sprintf(cmd_buf, http_req_hdr_tmpl, argv[1], host, port, flag); result = send(http_sock, cmd_buf, send_len, 0); if (result == SOCKET_ERROR) /* 发送失败 */ { printf("[Web] fail to send, error = %d\n", WSAGetLastError()); return -1; }
可以看到,我们使用了send()函数,其中cmd_buf是消息头内容。此时服务器接收对应信息:
acpt_soc = accept(srv_soc, (struct sockaddr *) &from_addr, &from_len); if (acpt_soc == INVALID_SOCKET) /* 接受失败 */ { printf("[Web] Fail to accept, error = %d\n", WSAGetLastError()); break; } printf("[Web] Accepted address:[%s], port:[%d]\n", inet_ntoa(from_addr.sin_addr), ntohs(from_addr.sin_port)); recv_len = recv(acpt_soc, cmd_buf, HTTP_BUF_SIZE, 0); if (recv_len == SOCKET_ERROR) /* 接收失败 */ { closesocket(acpt_soc); printf("[Web] Fail to recv, error = %d\n", WSAGetLastError()); break; }
我们用accept()函数接受连接建立,然后recv()函数接收客户端的内容。服务器端接收到控制指令后打开对应的文件并读取,回传:
res_file = fopen(filename, "rb+"); /* 用二进制格式打开文件 */ if (res_file == NULL) { printf("[Web] The file [%s] is not existed\n", filename); return 0; } fseek(res_file, 0, SEEK_END); file_len = ftell(res_file); fseek(res_file, 0, SEEK_SET); type = http_get_type_by_suffix(suffix); /* 文件对应的 Content-Type */ if (type == NULL) { printf("[Web] There is not the related content type\n"); return 0; } do /* 发送文件, HTTP 的消息体 */ { read_len = fread(data_buf, sizeof(char), HTTP_BUF_SIZE, res_file); if (read_len > 0) { send_len = send(soc, data_buf, read_len, 0); file_len -= read_len; } } while ((read_len > 0) && (file_len > 0)); fclose(res_file); return 1;
以此类推,上传文件基本操作也只是逆操作。
到这里,一个简易的上传下载文件项目已经完成;在这里应该注意的是:定义的消息体变量buf应设为外部变量,若只是局部变量,当索要内存过大时,压栈会stack overflow,而外部变量主要压入堆里。
0 0
- 基于http传输(二)
- 超文本传输协议HTTP(二)
- 基于RTP的h.264视频传输系统(二)
- 基于ProtoBuf协议实现网络传输(二)
- HTTP(超文本传输协议)
- 超文本传输协议(HTTP)
- 超文本传输协议(HTTP)
- 超文本传输协议(HTTP)
- HTTP断点续传(分块传输)
- HTTP断点续传(分块传输)
- 浅谈前端性能优化(二)——对HTTP传输进行压缩
- Springboot 实现 Restful 服务,基于 HTTP / JSON 传输
- Springboot 实现 Restful 服务,基于 HTTP / JSON 传输
- Springboot 实现 Restful 服务,基于 HTTP / JSON 传输
- Springboot 实现 Restful 服务,基于 HTTP / JSON 传输
- FPGA综合系统设计(二):基于FPGA的温度采集和以太网传输
- 基于UDP的新一代多路传输协议—QUIC(二)
- 基于iOS的网络音视频实时传输系统(二)- 捕获音视频数据
- JAVAWEB开发之国际化与Ajax(重点)详解(以及jsonlib、xsream的使用)
- ListView取消默认点击背景颜色
- OkHttp保存和使用cookie
- Redis配置和简单应用
- 用nexus搭建maven私服
- 基于http传输(二)
- 使用CocoaPod出现-bash: pod: command not found 解决办法
- elasticsearch索引自动清理
- 初学python:模块化编程
- 在PHP中使用计划任务
- 5.3Pattern,Date,Calendar,DateFormat
- 为什么直接杀死线程是不好的
- LeetCode-110. Balanced Binary Tree
- caffe初探之-caffe使用CIFAR-10数据集训练网络