diff --git a/trunk/research/msg_zerocopy/.gitignore b/trunk/research/msg_zerocopy/.gitignore new file mode 100644 index 000000000..3ddc9a018 --- /dev/null +++ b/trunk/research/msg_zerocopy/.gitignore @@ -0,0 +1,2 @@ +server +client \ No newline at end of file diff --git a/trunk/research/msg_zerocopy/Makefile b/trunk/research/msg_zerocopy/Makefile new file mode 100644 index 000000000..628939550 --- /dev/null +++ b/trunk/research/msg_zerocopy/Makefile @@ -0,0 +1,8 @@ + +default: server client + +server: server.cpp ../../objs/st/libst.a + gcc -g -O0 -I../../objs/st/ $^ -o $@ + +client: client.cpp ../../objs/st/libst.a + gcc -g -O0 -I../../objs/st/ $^ -o $@ diff --git a/trunk/research/msg_zerocopy/client.cpp b/trunk/research/msg_zerocopy/client.cpp new file mode 100644 index 000000000..c30f3584d --- /dev/null +++ b/trunk/research/msg_zerocopy/client.cpp @@ -0,0 +1,61 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char** argv) +{ + if (argc < 3) { + printf("Usage: %s \n", argv[0]); + printf("For example:\n"); + printf(" %s 127.0.0.1 8000\n", argv[0]); + exit(-1); + } + + assert(!st_set_eventsys(ST_EVENTSYS_ALT)); + assert(!st_init()); + + int fd = socket(PF_INET, SOCK_DGRAM, 0); + assert(fd > 0); + + st_netfd_t stfd = st_netfd_open_socket(fd); + assert(stfd); + + sockaddr_in peer; + memset(&peer, 0, sizeof(sockaddr_in)); + + int port = 8000; + const char* host = "127.0.0.1"; + peer.sin_family = AF_INET; + peer.sin_port = htons(port); + peer.sin_addr.s_addr = inet_addr(host); + + char buf[1500]; + memset(buf, 0, sizeof(buf)); + memcpy(buf, "Hello", 5); + + iovec iov; + iov.iov_base = buf; + iov.iov_len = strlen(buf); + + msghdr msg; + memset(&msg, 0, sizeof(msghdr)); + msg.msg_name = (sockaddr_in*)&peer; + msg.msg_namelen = sizeof(sockaddr_in); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + + int r0 = st_sendmsg(stfd, &msg, 0, ST_UTIME_NO_TIMEOUT); + printf("Ping %s:%d %d bytes, r0=%d, %s\n", host, port, iov.iov_len, r0, msg.msg_iov->iov_base); + + r0 = st_recvmsg(stfd, &msg, 0, ST_UTIME_NO_TIMEOUT); + assert(r0 > 0); + printf("From %s:%d %d bytes, flags %#x, %s\n", inet_ntoa(peer.sin_addr), ntohs(peer.sin_port), r0, + msg.msg_flags, msg.msg_iov->iov_base); + + return 0; +} diff --git a/trunk/research/msg_zerocopy/server.cpp b/trunk/research/msg_zerocopy/server.cpp new file mode 100644 index 000000000..cc1259680 --- /dev/null +++ b/trunk/research/msg_zerocopy/server.cpp @@ -0,0 +1,79 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char** argv) +{ + if (argc < 3) { + printf("Usage: %s \n", argv[0]); + printf("For example:\n"); + printf(" %s 0.0.0.0 8000\n", argv[0]); + exit(-1); + } + + assert(!st_set_eventsys(ST_EVENTSYS_ALT)); + assert(!st_init()); + + int fd = socket(PF_INET, SOCK_DGRAM, 0); + assert(fd > 0); + + int n = 1; + int r0 = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&n, sizeof(n)); + assert(!r0); + + sockaddr_in addr; + memset(&addr, 0, sizeof(sockaddr_in)); + + int port = 8000; + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.s_addr = inet_addr("0.0.0.0"); + + r0 = bind(fd, (sockaddr *)&addr, sizeof(sockaddr_in)); + assert(!r0); + + st_netfd_t stfd = st_netfd_open_socket(fd); + assert(stfd); + + printf("Listen at udp://%d\n", port); + + msghdr msg; + memset(&msg, 0, sizeof(msghdr)); + + sockaddr_in peer; + memset(&peer, 0, sizeof(sockaddr_in)); + msg.msg_name = (sockaddr_in*)&peer; + msg.msg_namelen = sizeof(sockaddr_in); + + char buf[1500]; + memset(buf, 0, sizeof(buf)); + + iovec iov; + memset(&iov, 0, sizeof(iovec)); + iov.iov_base = buf; + iov.iov_len = sizeof(buf); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + + while (true) { + r0 = st_recvmsg(stfd, &msg, 0, ST_UTIME_NO_TIMEOUT); + assert(r0 > 0); + printf("From %s:%d %d bytes, flags %#x, %s\n", inet_ntoa(peer.sin_addr), ntohs(peer.sin_port), r0, + msg.msg_flags, msg.msg_iov->iov_base); + + memcpy(msg.msg_iov->iov_base, "World", 5); + msg.msg_iov->iov_len = 5; + + r0 = st_sendmsg(stfd, &msg, 0, ST_UTIME_NO_TIMEOUT); + assert(r0 > 0); + printf("Pong %s:%d %d bytes, flags %#x, %s\n", inet_ntoa(peer.sin_addr), ntohs(peer.sin_port), r0, + msg.msg_flags, msg.msg_iov->iov_base); + } + + return 0; +}