設置套接字選項SO_LINGER爲(on, 0)後關閉套接字,將當即向對端發送TCP RST。c++
對端接收TCP RST後:socket
進行讀操做:tcp
下面用代碼進行驗證(使用SIren庫)。oop
#include <cassert> #include <cstdio> #include <siren/ip_endpoint.h> #include <siren/loop.h> #include <siren/stream.h> #include <siren/tcp_socket.h> using namespace siren; int main() { Loop l(16 * 1024); l.createFiber([&] () -> void { TCPSocket ss(&l); ss.setReuseAddress(true); ss.listen(IPEndpoint(0, 0)); IPEndpoint ipe = ss.getLocalEndpoint(); Event e = l.makeEvent(); l.createFiber([&] () -> void { /* mark */ std::puts("step 2"); TCPSocket cs(&l); cs.connect(ipe); e.waitFor(); /* mark */ std::puts("step 5"); cs.setNoDelay(true); cs.closeWrite(); // 發送TCP FIN cs.setLinger(true, 0); // cs析構時調用close()將向對端發送TCP RST /* mark */ std::puts("step 6"); }); /* mark */ std::puts("step 1"); TCPSocket cs = ss.accept(); /* mark */ std::puts("step 3"); e.trigger(); cs.setNoDelay(true); /* mark */ std::puts("step 4"); l.usleep(1000000); // 接收對端發送的TCP FIN和TCP RST /* mark */ std::puts("step 7"); Stream s; s.reserveBuffer(1); assert(cs.read(&s) == 0); // 無異常,無數據 /* mark */ std::puts("step 8"); }); l.run(); return 0; }
編譯運行spa
# g++ -std=c++14 test.cc -lsiren -lpthread && ./a.out step 1 step 2 step 3 step 4 step 5 step 6 step 7 step 8
#include <cstdio> #include <siren/ip_endpoint.h> #include <siren/loop.h> #include <siren/stream.h> #include <siren/tcp_socket.h> using namespace siren; int main() { Loop l(16 * 1024); l.createFiber([&] () -> void { TCPSocket ss(&l); ss.setReuseAddress(true); ss.listen(IPEndpoint(0, 0)); IPEndpoint ipe = ss.getLocalEndpoint(); Event e = l.makeEvent(); l.createFiber([&] () -> void { /* mark */ std::puts("step 2"); TCPSocket cs(&l); cs.connect(ipe); e.waitFor(); /* mark */ std::puts("step 5"); cs.setNoDelay(true); cs.setLinger(true, 0); // cs析構時調用close()將向對端發送TCP RST /* mark */ std::puts("step 6"); }); /* mark */ std::puts("step 1"); TCPSocket cs = ss.accept(); /* mark */ std::puts("step 3"); e.trigger(); cs.setNoDelay(true); /* mark */ std::puts("step 4"); l.usleep(1000000); // 接收對端發送的TCP RST /* mark */ std::puts("step 7"); Stream s; s.reserveBuffer(1); cs.read(&s); // 拋出異常 /* mark */ std::puts("step 8"); }); l.run(); return 0; }
編譯運行code
# g++ -std=c++14 test.cc -lsiren -lpthread && ./a.out step 1 step 2 step 3 step 4 step 5 step 6 step 7 terminate called after throwing an instance of 'std::system_error' what(): read() failed: Connection reset by peer Aborted
#include <cstdio> #include <siren/ip_endpoint.h> #include <siren/loop.h> #include <siren/stream.h> #include <siren/tcp_socket.h> using namespace siren; int main() { Loop l(16 * 1024); l.createFiber([&] () -> void { TCPSocket ss(&l); ss.setReuseAddress(true); ss.listen(IPEndpoint(0, 0)); IPEndpoint ipe = ss.getLocalEndpoint(); Event e = l.makeEvent(); l.createFiber([&] () -> void { /* mark */ std::puts("step 2"); TCPSocket cs(&l); cs.connect(ipe); e.waitFor(); /* mark */ std::puts("step 5"); cs.setNoDelay(true); cs.closeWrite(); // 發送TCP FIN cs.setLinger(true, 0); // cs析構時調用close()將向對端發送TCP RST /* mark */ std::puts("step 6"); }); /* mark */ std::puts("step 1"); TCPSocket cs = ss.accept(); /* mark */ std::puts("step 3"); e.trigger(); cs.setNoDelay(true); /* mark */ std::puts("step 4"); l.usleep(1000000); // 接收對端發送的TCP FIN和TCP RST /* mark */ std::puts("step 7"); Stream s; s.write("a", 1); cs.write(&s); // 拋出異常 /* mark */ std::puts("step 8"); }); l.run(); return 0; }
編譯運行ip
# g++ -std=c++14 test.cc -lsiren -lpthread && ./a.out step 1 step 2 step 3 step 4 step 5 step 6 step 7 terminate called after throwing an instance of 'std::system_error' what(): send() failed: Broken pipe Aborted
#include <cstdio> #include <siren/ip_endpoint.h> #include <siren/loop.h> #include <siren/stream.h> #include <siren/tcp_socket.h> using namespace siren; int main() { Loop l(16 * 1024); l.createFiber([&] () -> void { TCPSocket ss(&l); ss.setReuseAddress(true); ss.listen(IPEndpoint(0, 0)); IPEndpoint ipe = ss.getLocalEndpoint(); Event e = l.makeEvent(); l.createFiber([&] () -> void { /* mark */ std::puts("step 2"); TCPSocket cs(&l); cs.connect(ipe); e.waitFor(); /* mark */ std::puts("step 5"); cs.setNoDelay(true); cs.setLinger(true, 0); // cs析構時調用close()將向對端發送TCP RST /* mark */ std::puts("step 6"); }); /* mark */ std::puts("step 1"); TCPSocket cs = ss.accept(); /* mark */ std::puts("step 3"); e.trigger(); cs.setNoDelay(true); /* mark */ std::puts("step 4"); l.usleep(1000000); // 接收對端發送的TCP RST /* mark */ std::puts("step 7"); Stream s; s.write("a", 1); cs.write(&s); // 拋出異常 /* mark */ std::puts("step 8"); }); l.run(); return 0; }
編譯運行get
# g++ -std=c++14 test.cc -lsiren -lpthread && ./a.out step 1 step 2 step 3 step 4 step 5 step 6 step 7 terminate called after throwing an instance of 'std::system_error' what(): send() failed: Connection reset by peer Aborted