natplaindatagramsocketimpl.cc

来自「gcc3.2.1源代码」· CC 代码 · 共 704 行 · 第 1/2 页

CC
704
字号
/* Copyright (C) 1999, 2000, 2002  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>#ifdef WIN32#include <errno.h>#include <string.h>#ifndef ENOPROTOOPT#define ENOPROTOOPT 109#endifstatic inline intclose(int s){  return closesocket(s);}#else /* WIN32 */#ifdef HAVE_SYS_SOCKET_H#include <sys/socket.h>#endif#ifdef HAVE_NETINET_IN_H#include <netinet/in.h>#endif#ifdef HAVE_ARPA_INET_H#include <arpa/inet.h>#endif#include <errno.h>#include <string.h>#endif /* WIN32 */#if HAVE_BSTRING_H// Needed for bzero, implicitly used by FD_ZERO on IRIX 5.2 #include <bstring.h>#endif#ifndef DISABLE_JAVA_NET// Avoid macro definitions of bind from system headers, e.g. on// Solaris 7 with _XOPEN_SOURCE.  FIXMEstatic inline int_Jv_bind (int fd, struct sockaddr *addr, int addrlen){  return ::bind (fd, addr, addrlen);}#endif /* DISABLE_JAVA_NET */#ifdef bind#undef bind#endif#include <gcj/cni.h>#include <java/io/IOException.h>#include <java/io/InterruptedIOException.h>#include <java/net/BindException.h>#include <java/net/SocketException.h>#include <java/net/PlainDatagramSocketImpl.h>#include <java/net/InetAddress.h>#include <java/net/DatagramPacket.h>#include <java/lang/InternalError.h>#include <java/lang/Object.h>#include <java/lang/Boolean.h>#include <java/lang/Integer.h>// FIXME: remove these#define BooleanClass java::lang::Boolean::class$#define IntegerClass java::lang::Integer::class$#ifdef DISABLE_JAVA_NETvoidjava::net::PlainDatagramSocketImpl::create (){  throw new SocketException (    JvNewStringLatin1 ("DatagramSocketImpl.create: unimplemented"));}voidjava::net::PlainDatagramSocketImpl::bind (jint, java::net::InetAddress *){  throw new BindException (    JvNewStringLatin1 ("DatagramSocketImpl.bind: unimplemented"));}jintjava::net::PlainDatagramSocketImpl::peek (java::net::InetAddress *){  throw new java::io::IOException (    JvNewStringLatin1 ("DatagramSocketImpl.peek: unimplemented"));}voidjava::net::PlainDatagramSocketImpl::close (){  throw new java::io::IOException (    JvNewStringLatin1 ("DatagramSocketImpl.close: unimplemented"));}voidjava::net::PlainDatagramSocketImpl::send (java::net::DatagramPacket *){  throw new java::io::IOException (    JvNewStringLatin1 ("DatagramSocketImpl.send: unimplemented"));}voidjava::net::PlainDatagramSocketImpl::receive (java::net::DatagramPacket *){  throw new java::io::IOException (    JvNewStringLatin1 ("DatagramSocketImpl.receive: unimplemented"));}voidjava::net::PlainDatagramSocketImpl::setTimeToLive (jint){  throw new java::io::IOException (    JvNewStringLatin1 ("DatagramSocketImpl.setTimeToLive: unimplemented"));}jintjava::net::PlainDatagramSocketImpl::getTimeToLive (){  throw new java::io::IOException (    JvNewStringLatin1 ("DatagramSocketImpl.getTimeToLive: unimplemented"));}voidjava::net::PlainDatagramSocketImpl::mcastGrp (java::net::InetAddress *,					      jboolean){  throw new java::io::IOException (    JvNewStringLatin1 ("DatagramSocketImpl.mcastGrp: unimplemented"));}voidjava::net::PlainDatagramSocketImpl::setOption (jint, java::lang::Object *){  throw new SocketException (    JvNewStringLatin1 ("DatagramSocketImpl.setOption: unimplemented"));}java::lang::Object *java::net::PlainDatagramSocketImpl::getOption (jint){  throw new SocketException (    JvNewStringLatin1 ("DatagramSocketImpl.getOption: unimplemented"));}#else /* DISABLE_JAVA_NET */#ifndef HAVE_SOCKLEN_Ttypedef int socklen_t;#endifunion SockAddr{  struct sockaddr_in address;#ifdef HAVE_INET6  struct sockaddr_in6 address6;#endif};union McastReq{#if HAVE_STRUCT_IP_MREQ  struct ip_mreq mreq;#endif#if HAVE_STRUCT_IPV6_MREQ  struct ipv6_mreq mreq6;#endif};union InAddr{  struct in_addr addr;#ifdef HAVE_INET6  struct in6_addr addr6;#endif};// FIXME: routines here and/or in natPlainSocketImpl.cc could throw// NoRouteToHostException; also consider UnknownHostException, ConnectException.voidjava::net::PlainDatagramSocketImpl::create (){  int sock = ::socket (AF_INET, SOCK_DGRAM, 0);  if (sock < 0)    {      char* strerr = strerror (errno);      throw new java::net::SocketException (JvNewStringUTF (strerr));    }  _Jv_platform_close_on_exec (sock);  // We use fnum in place of fd here.  From leaving fd null we avoid  // the double close problem in FileDescriptor.finalize.  fnum = sock;}voidjava::net::PlainDatagramSocketImpl::bind (jint lport,					  java::net::InetAddress *host){  union SockAddr u;  struct sockaddr *ptr = (struct sockaddr *) &u.address;  // FIXME: Use getaddrinfo() to get actual protocol instead of assuming ipv4.  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 (_Jv_bind (fnum, ptr, len) == 0)    {      socklen_t addrlen = sizeof(u);      if (lport != 0)        localPort = lport;      else if (::getsockname (fnum, (sockaddr*) &u, &addrlen) == 0)        localPort = ntohs (u.address.sin_port);      else        goto error;      /* Allow broadcast by default. */      int broadcast = 1;      if (::setsockopt (fnum, SOL_SOCKET, SO_BROADCAST, (char *) &broadcast,                         sizeof (broadcast)) != 0)        goto error;      return;    } error:  char* strerr = strerror (errno);  throw new java::net::BindException (JvNewStringUTF (strerr));}jintjava::net::PlainDatagramSocketImpl::peek (java::net::InetAddress *i){  // FIXME: Deal with Multicast and if the socket is connected.  union SockAddr u;  socklen_t addrlen = sizeof(u);  ssize_t retlen =    ::recvfrom (fnum, (char *) NULL, 0, MSG_PEEK, (sockaddr*) &u,      &addrlen);  if (retlen < 0)    goto error;  // FIXME: Deal with Multicast addressing and if the socket is connected.  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"));  i->addr = raddr;  return rport; error:  char* strerr = strerror (errno);  throw new java::io::IOException (JvNewStringUTF (strerr));}// Close(shutdown) the socket.voidjava::net::PlainDatagramSocketImpl::close (){  // Avoid races from asynchronous finalization.  JvSynchronize sync (this);  // The method isn't declared to throw anything, so we disregard  // the return value.  ::close (fnum);  fnum = -1;  timeout = 0;}voidjava::net::PlainDatagramSocketImpl::send (java::net::DatagramPacket *p){  // FIXME: Deal with Multicast and if the socket is connected.  jint rport = p->getPort();  union SockAddr u;  jbyteArray haddress = p->getAddress()->addr;  jbyte *bytes = elements (haddress);  int len = haddress->length;  struct sockaddr *ptr = (struct sockaddr *) &u.address;  jbyte *dbytes = elements (p->getData());  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 (::sendto (fnum, (char *) dbytes, p->getLength(), 0, ptr, len) >= 0)    return;  char* strerr = strerror (errno);  throw new java::io::IOException (JvNewStringUTF (strerr));}void

⌨️ 快捷键说明

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