asio教程 Mac
1、命令行编译例子
g++ async_tcp_echo_server.cpp -I/Users/wangt/Desktop/wang/ccodes/asio-1.22.1/include -D ASIO_STANDALONE -std=c++11 -stdlib=libc++
原来需要加上的是-std=c++11 -stdlib=libc++ 而非其他
教程就在这个文件夹:--
file:///F:/Cpan/vs2019repos/TestAsio/asio-1.12.2/doc/index.html
https://www.cnblogs.com/ylcc-zyq/p/14960616.html
1、客户端
//common.h #pragma once #define COMMAND_MSG_LIST 0X60 #define COMMAND_MSG_GET 0X70 #define COMMAND_MSG_PUT 0X80 #define COMMAND_MSG_DATA 0X91 struct msgHead { int commandNo; int length; char cmd[512-8]; }; //main.cpp #include <cstdlib> #include <iostream> #include <memory> #include <utility> #include <asio/ts/buffer.hpp> #include <asio/ts/internet.hpp> #include <cstdlib> #include <cstring> #include <iostream> #include "asio.hpp" #include "common.h" #include <fstream> using namespace std; using asio::ip::tcp; enum { max_length = 1024 }; void listFilesCmd(tcp::socket& s) { msgHead msg1; msg1.commandNo = COMMAND_MSG_LIST; asio::write(s, asio::buffer((char*)&msg1, sizeof(msg1))); msgHead msgre; size_t reply_length = asio::read(s, asio::buffer(&msgre, sizeof(msgre))); std::cout << "Reply is: "; std::cout << msgre.cmd; std::cout << "\n"; } void getFileCmd(tcp::socket& s) { msgHead msg1; msg1.commandNo = COMMAND_MSG_GET; strcpy(msg1.cmd, ".//test1.cpp"); asio::write(s, asio::buffer((char*)&msg1, sizeof(msg1))); msgHead msgre; size_t reply_length = asio::read(s, asio::buffer(&msgre, sizeof(msgre))); int length = msgre.length; if (COMMAND_MSG_GET + 1 == msgre.commandNo) { cout << "file rply err!" << endl; return; } ofstream ofs; ofs.open("mytest0524.rcv", ios::out); while (length > 0) { BYTE buf[512]; int stepRead = 512; if (length < 512) stepRead = length; size_t len = asio::read(s, asio::buffer(&buf, stepRead)); /* asio::error_code error; size_t len = s.read_some(asio::buffer(buf), error); if (error == asio::error::eof) break; // Connection closed cleanly by peer. else if (error) throw asio::system_error(error); */ length -= len; ofs.write((char*)buf, len); ofs.flush(); } ofs.close(); } std::streampos fileSize(const char* filePath) { std::streampos fsize = 0; std::ifstream file(filePath, std::ios::binary); fsize = file.tellg(); file.seekg(0, std::ios::end); fsize = file.tellg() - fsize; file.close(); return fsize; } void putFileCmd(tcp::socket& s) { std::string full_path = ""; std::ifstream is(full_path.c_str(), std::ios::in | std::ios::binary); if (!is) { cout << "file not fine" << endl; return; } msgHead msg1; msg1.length = fileSize(full_path.c_str()); msg1.commandNo = COMMAND_MSG_PUT; strcpy(msg1.cmd, "test1.cpp"); asio::write(s, asio::buffer((char*)&msg1, sizeof(msg1))); char buf[512]; while (is.read(buf, sizeof(buf)).gcount() > 0) { asio::write(s, asio::buffer(buf, is.gcount())); } is.close(); //这个肯定ok---,to thi } int main(int argc, char* argv[]) { try {/* if (argc != 3) { std::cerr << "Usage: blocking_tcp_echo_client <host> <port>\n"; return 1; } */ asio::io_context io_context; tcp::socket s(io_context); tcp::resolver resolver(io_context); asio::connect(s, resolver.resolve("127.0.0.1", "1234")); //getFileCmd(s); listFilesCmd(s); } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; } return 0; }
2、服务器端
//common.cpp .h的一样 #include <io.h> #include <string> #include <vector> void getDirFiles(string dir, vector<string>& files) { //文件句柄 long hFile = 0; //文件信息 struct _finddata_t fileinfo; string p; if ((hFile = _findfirst(p.assign(dir).append("/*").c_str(), &fileinfo)) != -1) { do { //如果是目录,迭代之 //如果不是,加入列表 if ((fileinfo.attrib & _A_SUBDIR)) { //if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0) // getFiles(p.assign(path).append("/").append(fileinfo.name), files); } else { files.push_back(p.assign(dir).append("/").append(fileinfo.name)); } } while (_findnext(hFile, &fileinfo) == 0); _findclose(hFile); } } //main.cpp #include <cstdlib> #include <iostream> #include <memory> #include <utility> #include <asio/ts/buffer.hpp> #include <asio/ts/internet.hpp> #include <cstdlib> #include <iostream> #include <thread> #include <utility> #include "asio.hpp" #include "common.h" #include <fstream> extern void getDirFiles(string dir, vector<string>& files); using asio::ip::tcp; using namespace std; const int max_length = 1024; #define RCV_CMD_STATUE 0 #define RCV_DATA_STATUE 1 int statue = RCV_CMD_STATUE; string rcvBuffer; std::streampos fileSize(const char* filePath) { std::streampos fsize = 0; std::ifstream file(filePath, std::ios::binary); fsize = file.tellg(); file.seekg(0, std::ios::end); fsize = file.tellg() - fsize; file.close(); return fsize; } void parse(BYTE* buf,int length, tcp::socket& sock) { msgHead remsg; memset(&remsg,0,sizeof(remsg)); remsg.commandNo = buf[0]; msgHead* pMsg = (msgHead*)buf; if (RCV_CMD_STATUE == statue) { BYTE b0 = buf[0]; if (COMMAND_MSG_LIST == b0) { vector<string> vecFiles; getDirFiles("./", vecFiles); string strA; for (auto item : vecFiles) { strA.append(item); strA.append(" "); } strcpy(remsg.cmd, strA.c_str()); asio::write(sock, asio::buffer((BYTE*)&remsg, sizeof(remsg))); } else if (COMMAND_MSG_GET == b0) { //strcpy(remsg.cmd, "list1"); //asio::write(sock, asio::buffer("get", length)); string fileName(pMsg->cmd); std::string full_path = fileName; remsg.length = fileSize(full_path.c_str()); std::ifstream is(full_path.c_str(), std::ios::in | std::ios::binary); if (!is) { remsg.commandNo = b0 + 1; // rep = reply::stock_reply(reply::not_found); strcpy(remsg.cmd, "not found!"); asio::write(sock, asio::buffer((BYTE*)&remsg, sizeof(remsg))); return; } int iSize = fileSize(full_path.c_str()); asio::write(sock, asio::buffer((BYTE*)&remsg, sizeof(remsg))); // Fill out the reply to be sent to the client. char buf[512]; while (is.read(buf, sizeof(buf)).gcount() > 0) { asio::write(sock, asio::buffer(buf, is.gcount())); } is.close(); } else if (COMMAND_MSG_PUT == b0) { //asio::write(sock, asio::buffer("a", length)); string fileName(pMsg->cmd); std::string full_path = fileName; int length = pMsg->length; ofstream ofs; ofs.open("mytest0524.put", ios::out); while (length > 0) { BYTE buf[512]; int stepRead = 512; if (length < 512) stepRead = length; size_t len = asio::read(sock, asio::buffer(&buf, stepRead)); length -= len; ofs.write((char*)buf, len); ofs.flush(); } ofs.close(); } else { cout << "wrong" << endl; } } } void session(tcp::socket sock) { try { for (;;) { BYTE data[max_length]; asio::error_code error; size_t length = sock.read_some(asio::buffer(data), error); if (error == asio::error::eof) break; // Connection closed cleanly by peer. else if (error) throw asio::system_error(error); // Some other error. parse(data, length,sock); /* msgHead remsg; strcpy(remsg.cmd,"20220524"); std::cout << data << std::endl; asio::write(sock, asio::buffer(&remsg,sizeof(remsg) )); */ } } catch (std::exception& e) { std::cerr << "Exception in thread: " << e.what() << "\n"; } } void server(asio::io_context& io_context, unsigned short port) { tcp::acceptor a(io_context, tcp::endpoint(tcp::v4(), port)); for (;;) { std::thread(session, a.accept()).detach(); } } int main(int argc, char* argv[]) { try { asio::io_context io_context; server(io_context, 1234); } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; } return 0; }