C++实现服务器发送图片
这里是一个简单的图片服务器,每次向这个服务器发送请求后,都会得到一个图片。
特点:
- 负责发送图片的函数,接收的是string类型的值
重点:
- 在获取string图片的
char*
数据时,不能使用c_str()
,应该使用data()
原因是
c_str()
在获取char*
类型的数据时,会将\0
第一次出现的位置作为字符串结束的位置,而data()
则会返回整个字符串中的所有字符,包括可能在中间出现的\0
。
- 同理,如果想使用
append(char*)
函数,但是字符串中含有\0
,则应该使用append(char* s, int size)
- 使用中间带有
\0
的C字符串构造一个string类型的对象时,应该使用string(char* s, int size)
负责发送图片的函数
int send_image(int & fd, std::string& image){
// 创建响应实体
int body_length = image.size();
const char * body = image.data();
int response_length = body_length;
char * buffer = new char[response_length];
memcpy(buffer, body, body_length); // 写入图片
// 将响应写入发送缓冲区,并发送
int ret = write(fd, buffer, response_length);
// 清理
delete [] buffer;
return ret;
关于读取图片的函数,参考:
https://blog.csdn.net/qq_29695701/article/details/84262492
关于简单的服务器的信息,参考:
https://blog.csdn.net/qq_29695701/article/details/83830108
请求图片
$ curl http://server_ip:8099 > fei_ji.jpg
全部代码:
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>
#include <string>
#include <fstream>
#include <sstream>
#define PORT 8099
#define LISTENQ 5
std::string read_image(const std::string& image_path);
int send_image(int & fd, std::string& image);
int main(){
int listenfd, connfd;
struct sockaddr_in servaddr;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
if(listenfd < 0){
std::cout << "create socketfd failed" <<std::endl;
return 0;
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(PORT);
int bind_ok = bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
if(bind_ok < 0){
std::cout << "bind socket with server address failed" <<std::endl;
return 0;
}
int listen_ok = listen(listenfd, LISTENQ);
if(listen_ok < 0){
std::cout << "listen socket failed" <<std::endl;
return 0;
}
std::string img = read_image("images/airplane.jpg");
int write_ok;
while(1){
connfd = accept(listenfd, NULL, NULL);
if(connfd < 0){
std::cout << "create connection socket failed" <<std::endl;
return 0;
}
write_ok = send_image(connfd, img);
if(write_ok < 0){
std::cout << "write info to connection socket failed" <<std::endl;
close(connfd);
return 0;
}
close(connfd);
}
}
std::string read_image(const std::string& image_path){
std::ifstream is(image_path.c_str(), std::ifstream::in);
is.seekg(0, is.end);
int flength = is.tellg();
is.seekg(0, is.beg);
char * buffer = new char[flength];
is.read(buffer, flength);
std::string image(buffer, flength);
return image;
}
int send_image(int & fd, std::string& image){
// 创建响应实体
int body_length = image.size();
const char * body = image.data();
int response_length = body_length;
char * buffer = new char[response_length];
memcpy(buffer, body, body_length);
// 将响应写入发送缓冲区,并发送
int ret = write(fd, buffer, response_length);
// 清理
delete [] buffer;
return ret;
}