/** * Copyright 2013, Landz and its contributors. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package z.znr; import org.junit.Test; import z.znr.event.EPollEventArray; import z.znr.event.FileDescriptorEPollEvent; import z.znr.socket.SocketAddressInet; import z.znr.socket.SocketOptions; import z.znr.socket.Sockets; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.hamcrest.core.Is.is; import static org.xnio.nativeimpl.Native.*; import static z.offheap.zmalloc.Allocator.allocate; import static z.offheap.zmalloc.Allocator.free; import static z.util.Throwables.uncheck; import static z.znr.Syscall.*; import static z.znr.event.EPollEvents.EPOLLIN; import static z.znr.socket.Sockets.*; import static z.znr.event.EPolls.*; /** * do kinds of experiment with EPoll */ public class SyscallIntegrationTestEPoll2 { static { System.setProperty("jnr.invoke.compile.dump", "false"); } public static final String MSG = "hello"; public static final long N = 1024*512; @Test public void test_syscall_socket() { int serverfd, suc, clientfd; long size; serverfd = Sockets.socketTcp(); // sys_socket( // Sockets.DomainFamily.INET, // Sockets.SocketType.SOCK_STREAM, // 0); assertThat(serverfd, greaterThan(0)); // System.out.println(sockfd); SocketAddressInet addr = new SocketAddressInet(SocketAddressInet.LOOPBACK_ADDRESS,12345); suc = bind(serverfd,addr); assertThat(suc, is(0)); suc = sys_listen(serverfd, 10); assertThat(suc, is(0)); //epoll int epfd = sys_epoll_create(512); assertThat(epfd, greaterThan(0)); FileDescriptorEPollEvent e = new FileDescriptorEPollEvent(); e.setEventMask(EPOLLIN); e.setFileDescriptor(serverfd); suc = epollAdd(epfd, serverfd, e); assertThat(suc, is(0)); //client spawnClientThread(addr); // clientThreadxnio(); // //wait on EPollEventArray events = new EPollEventArray(); // for (; ; ) { System.out.println("wait on the epoll instance: " + epfd); int n = epoll_wait(epfd, events, -1); assertThat(suc, greaterThanOrEqualTo(0)); System.out.println("got " + n + " ready fd now.");//TODO: sometimes n=0(signal) for (int i = 0; i < n; i++) { FileDescriptorEPollEvent fdev = events.getEvent(i, FileDescriptorEPollEvent.class); assertThat(fdev.getFileDescriptor(), is(serverfd)); System.out.println("server thread will block on accepting..."); while ( (clientfd = acceptNonBlock(serverfd)) < 0 ) { //Sockets.SocketType.SOCK_NONBLOCK } assertThat(clientfd, greaterThan(0)); System.out.println("server thread got a clientfd:" + clientfd); //ReceiveBuffer int sizeRcvBuf = SocketOptions.getOptReceiveBuffer(clientfd); assertThat(sizeRcvBuf, greaterThan(1024)); System.out.println("ReceiveBuffer#1 of clientfd:"+sizeRcvBuf); long sBuffer = allocate(N);//to hold "hello" System.out.println("server thread will block on reading..."); size = sys_read(clientfd, sBuffer, N); // while ( (size = sys_read(clientfd, sBuffer, N))<0){ // } // byte[] b = new byte[(int)N]; // while ( (size = readH(clientfd, b, 0, (int)N))<0){ // // // } // assertThat(size, is(N)); System.out.println("+++++server thread received "+ size + " bytes data."); //ReceiveBuffer sizeRcvBuf = SocketOptions.getOptReceiveBuffer(clientfd); assertThat(sizeRcvBuf, greaterThan(1024)); System.out.println("ReceiveBuffer#2 of clientfd:"+sizeRcvBuf); // StringBuilder msg = new StringBuilder(5); // for (int j = 0; j < size; j++) { // msg.append((char) UNSAFE.getByte(sBuffer + j)); // } // // System.out.println("and we got msg:" + msg); // assertThat(msg.toString(), is(MSG)); suc = sys_close(serverfd); assertThat(suc, is(0)); free(sBuffer); System.out.println("whole test done."); } // } } private void spawnClientThread(SocketAddressInet addr) { //client thread new Thread(()->{ uncheck(()->Thread.sleep(5_000L)); System.out.println("client thread start to work..."); int cfd = sys_socket( Sockets.DomainFamily.INET, Sockets.SocketType.SOCK_STREAM, 0); System.out.println("client thread now try to connect to server..."); int csuc = connect(cfd,addr); assertThat(csuc, is(0)); System.out.println("client thread connected."); long cBuffer = allocate(N); // for (int i = 0; i < MSG.length(); i++) { // UNSAFE.putByte(cBuffer+i, (byte)MSG.charAt(i)); // } //SendBuffer int sb = SocketOptions.getOptSendBuffer(cfd); assertThat(sb, greaterThan(1024)); System.out.println("SendBuffer:"+sb);// System.out.println("client thread will block on writing after 20s..."); uncheck(()->Thread.sleep(20_000L)); // int N = 100_000_0000;//FIXME: send n times msg? // for (int j = 0; j < N; j++) { long csize = sys_write(cfd,cBuffer,N); assertThat(csize,is(N)); // System.out.println("sent the "+j+"th msg."); // } //SendBuffer sb = SocketOptions.getOptSendBuffer(cfd); assertThat(sb, greaterThan(1024)); System.out.println("SendBuffer:"+sb);// System.out.println("client thread has sent out "+csize+" bytes data."); // //TODO: shutdown // csuc = sys_shutdown(cfd,Sockets.ShutDownType.SHUT_RD); // assertThat(csuc, is(0)); // // csuc = sys_shutdown(cfd,Sockets.ShutDownType.SHUT_WR); // assertThat(csuc, is(0)); // // //fail for repeating call? // csuc = sys_shutdown(cfd,Sockets.ShutDownType.SHUT_RDWR); // assertThat(csuc, is(0)); // csuc = sys_close(cfd); // assertThat(csuc, is(0)); // free(cBuffer); // uncheck(()->Thread.sleep(10_000L)); System.out.println("client thread done."); }).start(); } // public void clientThreadxnio() { // //====================================================== // //client thread // new Thread(()->{ // uncheck(()->Thread.sleep(1000L)); // // System.out.println("client thread start to work..."); // int cfd = socketTcp(); // byte[] addr = null; // try { // addr = encodeSocketAddress(getServerAddress()); // }catch (Exception e){e.printStackTrace();} // // System.out.println("client thread now try to connect to server..."); // int csuc=0; // while ( (csuc = connect(cfd, addr)) <0 ) { // } // assertThat(csuc, is(0)); // System.out.println("client thread connected."); // // byte[] cBuffer = new byte[(int)N];//allocate(N); // for (int i = 0; i < cBuffer.length; i++) { // cBuffer[i] = 66; // } // // System.out.println("client thread will block on writing..."); // long csize = writeH(cfd, cBuffer, 0, (int)N); // assertThat(csize,is(N)); // // //SendBuffer // int sb = SocketOptions.getOptSendBuffer(cfd); // assertThat(sb, greaterThan(1024)); // System.out.println("SendBuffer:"+sb);// // // System.out.println("client thread has sent out "+csize+" bytes data."); //// //// //TODO: shutdown //// csuc = sys_shutdown(cfd,Sockets.ShutDownType.SHUT_RD); //// assertThat(csuc, is(0)); //// //// csuc = sys_shutdown(cfd,Sockets.ShutDownType.SHUT_WR); //// assertThat(csuc, is(0)); //// //// //fail for repeating call? //// csuc = sys_shutdown(cfd,Sockets.ShutDownType.SHUT_RDWR); //// assertThat(csuc, is(0)); //// //// csuc = sys_close(cfd); //// assertThat(csuc, is(0)); //// free(cBuffer); // // uncheck(()->Thread.sleep(10_000L)); // System.out.println("client thread done."); // }).start(); // //====================================================== // // } // // // protected static SocketAddress getServerAddress() throws UnknownHostException { // return new InetSocketAddress(InetAddress.getByAddress(new byte[]{127, 0, 0, 1}), 12345); // } }