⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 natplainsocketimplwin32.cc

📁 gcc的组建
💻 CC
📖 第 1 页 / 共 2 页
字号:
/* Copyright (C) 2003, 2004, 2005 Free Software Foundation   This file is part of libgcj.This software is copyrighted work licensed under the terms of theLibgcj License.  Please consult the file "LIBGCJ_LICENSE" fordetails.  */#include <config.h>#include <platform.h>#undef STRICT#undef MAX_PRIORITY#undef MIN_PRIORITY#include <gnu/java/net/PlainSocketImpl.h>#include <gnu/java/net/PlainSocketImpl$SocketInputStream.h>#include <gnu/java/net/PlainSocketImpl$SocketOutputStream.h>#include <java/io/IOException.h>#include <java/net/BindException.h>#include <java/net/ConnectException.h>#include <java/net/InetAddress.h>#include <java/net/InetSocketAddress.h>#include <java/net/SocketException.h>#include <java/net/SocketTimeoutException.h>#include <java/lang/InternalError.h>#include <java/lang/Object.h>#include <java/lang/Boolean.h>#include <java/lang/Class.h>#include <java/lang/Integer.h>#include <java/lang/Thread.h>#include <java/lang/NullPointerException.h>#include <java/lang/ArrayIndexOutOfBoundsException.h>#include <java/lang/IllegalArgumentException.h>union SockAddr{  struct sockaddr_in address;#ifdef HAVE_INET6  struct sockaddr_in6 address6;#endif};voidgnu::java::net::PlainSocketImpl::create (jboolean stream){  SOCKET sock = ::socket (AF_INET, stream ? SOCK_STREAM : SOCK_DGRAM, 0);  if (sock == INVALID_SOCKET)    {      _Jv_ThrowIOException ();    }  // Cast this to a HANDLE so we can make  // it non-inheritable via _Jv_platform_close_on_exec.  HANDLE hSocket = (HANDLE) sock;  _Jv_platform_close_on_exec (hSocket);  // We use native_fd in place of fd here.  From leaving fd null we avoid  // the double close problem in FileDescriptor.finalize.  native_fd = (jint) hSocket;}voidgnu::java::net::PlainSocketImpl::bind (::java::net::InetAddress *host, jint lport){  union SockAddr u;  struct sockaddr *ptr = (struct sockaddr *) &u.address;  jbyteArray haddress = host->addr;  jbyte *bytes = elements (haddress);  int len = haddress->length;  if (len == 4)    {      u.address.sin_family = AF_INET;      if (host != NULL)        memcpy (&u.address.sin_addr, bytes, len);      else        u.address.sin_addr.s_addr = htonl (INADDR_ANY);      len = sizeof (struct sockaddr_in);      u.address.sin_port = htons (lport);    }#ifdef HAVE_INET6  else if (len == 16)    {      u.address6.sin6_family = AF_INET6;      memcpy (&u.address6.sin6_addr, bytes, len);      len = sizeof (struct sockaddr_in6);      u.address6.sin6_port = htons (lport);    }#endif  else    throw new ::java::net::SocketException (JvNewStringUTF ("invalid length"));  if (::bind (native_fd, ptr, len) != SOCKET_ERROR)    {      socklen_t addrlen = sizeof(u);      if (lport != 0)        localport = lport;      else if (::getsockname (native_fd, (sockaddr*) &u, &addrlen) != SOCKET_ERROR)        localport = ntohs (u.address.sin_port);      else        goto error;      return;    }error:  DWORD dwErrorCode = WSAGetLastError ();  throw new ::java::net::BindException (_Jv_WinStrError (dwErrorCode));}static voidthrowConnectException (DWORD dwErrorCode){  throw new ::java::net::ConnectException (_Jv_WinStrError (dwErrorCode));}static voidthrowConnectException (){  throwConnectException (WSAGetLastError ());}voidgnu::java::net::PlainSocketImpl::connect (::java::net::SocketAddress *addr,                                     jint timeout){  ::java::net::InetSocketAddress *tmp = (::java::net::InetSocketAddress*) addr;  ::java::net::InetAddress *host = tmp->getAddress();  jint rport = tmp->getPort();  // Set the SocketImpl's address and port fields before we try to  // connect.  Note that the fact that these are set doesn't imply  // that we're actually connected to anything.  We need to record  // this data before we attempt the connect, since non-blocking  // SocketChannels will use this and almost certainly throw timeout  // exceptions.  address = host;  port = rport;  union SockAddr u;  socklen_t addrlen = sizeof(u);  jbyteArray haddress = host->addr;  jbyte *bytes = elements (haddress);  int len = haddress->length;  struct sockaddr *ptr = (struct sockaddr *) &u.address;    if (len == 4)    {      u.address.sin_family = AF_INET;      memcpy (&u.address.sin_addr, bytes, len);      len = sizeof (struct sockaddr_in);      u.address.sin_port = htons (rport);    }#ifdef HAVE_INET6  else if (len == 16)    {      u.address6.sin6_family = AF_INET6;      memcpy (&u.address6.sin6_addr, bytes, len);      len = sizeof (struct sockaddr_in6);      u.address6.sin6_port = htons (rport);    }#endif  else    throw new ::java::net::SocketException (JvNewStringUTF ("invalid length"));  if (timeout > 0)    {      // FIXME: we're creating a fresh WSAEVENT for each connect().      WSAEventWrapper aWSAEventWrapper(native_fd, FD_CONNECT);      WSAEVENT hEvent = aWSAEventWrapper.getEventHandle ();      if (::connect (native_fd, ptr, len) == SOCKET_ERROR)      {        if (WSAGetLastError () != WSAEWOULDBLOCK)          throwConnectException ();        DWORD dwRet =          WSAWaitForMultipleEvents (1, &hEvent, true, timeout, false);            // use true, false instead of TRUE, FALSE because the            // MS constants got undefined        // Reset and ignore our thread's interrupted flag.        // It's not possible to interrupt these sort of        // operations on Win32 anyway.        ::java::lang::Thread::interrupted();        if (dwRet == WSA_WAIT_FAILED)          throwConnectException ();        else if (dwRet == WSA_WAIT_TIMEOUT)          throw new ::java::net::SocketTimeoutException            (JvNewStringUTF ("connect timed out"));                    // If we get here, we still need to check whether the actual        // connect() succeeded. Use any socket-specific error code        // instead of the thread-based one.        int nErrCode; int nErrLen=sizeof(nErrCode);        if (::getsockopt(native_fd, SOL_SOCKET, SO_ERROR, (char*) &nErrCode,          &nErrLen) == SOCKET_ERROR)          {            throwConnectException ();          }                if (nErrCode != NO_ERROR)          {            throwConnectException (nErrCode);          }      }    }  else    {      if (::connect (native_fd, ptr, len) == SOCKET_ERROR)        throwConnectException();    }  // A bind may not have been done on this socket; if so, set localport now.  if (localport == 0)    {      if (::getsockname (native_fd, (sockaddr*) &u, &addrlen) != SOCKET_ERROR)        localport = ntohs (u.address.sin_port);      else        throwConnectException();    }}voidgnu::java::net::PlainSocketImpl::listen (jint backlog){  if (::listen (native_fd, backlog) == SOCKET_ERROR)    {      _Jv_ThrowIOException ();    }}voidgnu::java::net::PlainSocketImpl::accept (gnu::java::net::PlainSocketImpl *s){  union SockAddr u;  socklen_t addrlen = sizeof(u);  HANDLE hSocket = 0;  SOCKET new_socket = 0;  if (timeout > 0)    {      // FIXME: we're creating a fresh WSAEVENT for each accept().      // One possible alternative would be that native_fd really points      // to an extended structure consisting of the SOCKET, its      // associated WSAEVENT, etc.      WSAEventWrapper aWSAEventWrapper(native_fd, FD_ACCEPT);      WSAEVENT hEvent = aWSAEventWrapper.getEventHandle ();      for (;;)      {        new_socket = ::accept (native_fd, (sockaddr*) &u, &addrlen);        if (new_socket != INVALID_SOCKET)        {          // This new child socket is nonblocking because the parent          // socket became nonblocking via the WSAEventSelect() call,          // so we set its mode back to blocking.          WSAEventSelect (new_socket, hEvent, 0);            // undo the hEvent <-> FD_ACCEPT association inherited            // inherited from our parent socket          unsigned long lSockOpt = 0L;            // blocking mode          if (ioctlsocket(new_socket, FIONBIO, &lSockOpt) == SOCKET_ERROR)          {            goto error;          }          break;        }        else if (WSAGetLastError () != WSAEWOULDBLOCK)          {            goto error;          }        DWORD dwRet =          WSAWaitForMultipleEvents (1, &hEvent, true, timeout, false);            // use true, false instead of TRUE, FALSE because the            // MS constants got undefined        // Reset and ignore our thread's interrupted flag.        ::java::lang::Thread::interrupted();        if (dwRet == WSA_WAIT_FAILED)          goto error;        else if (dwRet == WSA_WAIT_TIMEOUT)          throw new ::java::net::SocketTimeoutException            (JvNewStringUTF ("Accept timed out"));      }    }  else    {      new_socket = ::accept (native_fd, (sockaddr*) &u, &addrlen);    }  if (new_socket == INVALID_SOCKET)    goto error;  // Cast this to a HANDLE so we can make  // it non-inheritable via _Jv_platform_close_on_exec.  hSocket = (HANDLE) new_socket;  _Jv_platform_close_on_exec (hSocket);  jbyteArray raddr;  jint rport;  if (u.address.sin_family == AF_INET)    {      raddr = JvNewByteArray (4);      memcpy (elements (raddr), &u.address.sin_addr, 4);      rport = ntohs (u.address.sin_port);    }#ifdef HAVE_INET6  else if (u.address.sin_family == AF_INET6)    {      raddr = JvNewByteArray (16);      memcpy (elements (raddr), &u.address6.sin6_addr, 16);      rport = ntohs (u.address6.sin6_port);    }#endif  else    throw new ::java::net::SocketException (JvNewStringUTF ("invalid family"));  s->native_fd = (jint) hSocket;  s->localport = localport;  s->address = new ::java::net::InetAddress (raddr, NULL);  s->port = rport;  return; error:  _Jv_ThrowIOException ();}// Close(shutdown) the socket.voidgnu::java::net::PlainSocketImpl::close(){  // Avoid races from asynchronous finalization.  JvSynchronize sync (this);  // should we use shutdown here? how would that effect so_linger?  int res = ::closesocket (native_fd);  if (res == -1)    {      // These three errors are not errors according to tests performed      // on the reference implementation.      DWORD dwErr = WSAGetLastError();      if (dwErr != WSAENOTCONN && dwErr != WSAECONNRESET        && dwErr != WSAENOTSOCK)        _Jv_ThrowIOException ();    }  // Safe place to reset the file pointer.  native_fd = -1;  timeout = 0;}// Write a byte to the socket.voidgnu::java::net::PlainSocketImpl$SocketOutputStream::write(jint b){  jbyte d =(jbyte) b;  int r = 0;  while (r != 1)    {      r = ::send (this$0->native_fd, (char*) &d, 1, 0);      if (r == -1)        {          DWORD dwErr = WSAGetLastError();                    // Reset and ignore our thread's interrupted flag.          // It's not possible to interrupt these sort of          // operations on Win32 anyway.          ::java::lang::Thread::interrupted();          // Some errors should not cause exceptions.          if (dwErr != WSAENOTCONN && dwErr != WSAECONNRESET            && dwErr != WSAENOTSOCK)            _Jv_ThrowIOException ();          break;        }    }}// Write some bytes to the socket.voidgnu::java::net::PlainSocketImpl$SocketOutputStream::write(jbyteArray b,   jint offset, jint len){  if (! b)    throw new ::java::lang::NullPointerException;  if (offset < 0 || len < 0 || offset + len > JvGetArrayLength (b))    throw new ::java::lang::ArrayIndexOutOfBoundsException;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -