OSDN Git Service

iOS sockets implemented (untested)
authorChristoph Aschwanden <contact@noblemaster.com>
Sun, 7 Oct 2012 12:05:19 +0000 (21:05 +0900)
committerChristoph Aschwanden <contact@noblemaster.com>
Sun, 7 Oct 2012 12:05:19 +0000 (21:05 +0900)
backends/gdx-backend-iosmonotouch/src/com/badlogic/gdx/backends/ios/IOSNet.java
backends/gdx-backend-iosmonotouch/src/com/badlogic/gdx/backends/ios/IOSServerSocket.java [new file with mode: 0644]
backends/gdx-backend-iosmonotouch/src/com/badlogic/gdx/backends/ios/IOSSocket.java [new file with mode: 0644]
backends/gdx-backend-iosmonotouch/src/com/badlogic/gdx/backends/ios/IOSStreamInput.java [new file with mode: 0644]
backends/gdx-backend-iosmonotouch/src/com/badlogic/gdx/backends/ios/IOSStreamOutput.java [new file with mode: 0644]

index 310eea8..9b6029f 100755 (executable)
@@ -24,6 +24,7 @@ import com.badlogic.gdx.net.Socket;
 import com.badlogic.gdx.net.SocketHints;\r
 \r
 public class IOSNet implements Net {\r
+       \r
        @Override\r
        public HttpResult httpGet (String url, String... parameters) {\r
                throw new UnsupportedOperationException("Not implemented");\r
@@ -36,11 +37,11 @@ public class IOSNet implements Net {
 \r
        @Override\r
        public ServerSocket newServerSocket (Protocol protocol, int port, ServerSocketHints hints) {\r
-               throw new UnsupportedOperationException("Not implemented");\r
+               return new IOSServerSocket(protocol, port, hints);\r
        }\r
 \r
        @Override\r
        public Socket newClientSocket (Protocol protocol, String host, int port, SocketHints hints) {\r
-               throw new UnsupportedOperationException("Not implemented");\r
+               return new IOSSocket(protocol, host, port, hints);\r
        }\r
 }\r
diff --git a/backends/gdx-backend-iosmonotouch/src/com/badlogic/gdx/backends/ios/IOSServerSocket.java b/backends/gdx-backend-iosmonotouch/src/com/badlogic/gdx/backends/ios/IOSServerSocket.java
new file mode 100644 (file)
index 0000000..66d8ce1
--- /dev/null
@@ -0,0 +1,88 @@
+package com.badlogic.gdx.backends.ios;
+
+import java.net.InetSocketAddress;
+
+import cli.System.Net.Dns;
+import cli.System.Net.IPAddress;
+import cli.System.Net.Sockets.TcpListener;
+
+import com.badlogic.gdx.Net.Protocol;
+import com.badlogic.gdx.net.ServerSocket;
+import com.badlogic.gdx.net.ServerSocketHints;
+import com.badlogic.gdx.net.Socket;
+import com.badlogic.gdx.net.SocketHints;
+import com.badlogic.gdx.utils.GdxRuntimeException;
+
+/**
+ * iOS server socket implementation using System.Net.Sockets.TcpListener (Microsoft).
+ * 
+ * @author noblemaster
+ */
+public class IOSServerSocket implements ServerSocket {
+
+       private Protocol protocol;
+       
+       /** Our listener or null for disposed, aka closed. */
+       private TcpListener listener;
+
+       
+       public IOSServerSocket(Protocol protocol, int port, ServerSocketHints hints) {
+               if (protocol == Protocol.TCP) {
+                       this.protocol = protocol;
+                       
+                       // create the server socket
+                       try {
+                               // initialize
+                               IPAddress ipAddress = Dns.GetHostEntry("localhost").get_AddressList()[0];
+                               listener = new TcpListener(ipAddress, port);
+                               if (hints != null) {
+                                       // NOTE: most server socket hints are not available on iOS - no performance parameters!
+                                       listener.set_ExclusiveAddressUse(!hints.reuseAddress);
+                               }
+                               
+                               // and bind the server...
+                               InetSocketAddress address = new InetSocketAddress(port);
+                               if (hints != null) {
+                                       listener.Start(hints.backlog);
+                               }
+                               else {
+                                       listener.Start();
+                               }
+                       }
+                       catch (Exception e) {
+                               throw new GdxRuntimeException("Cannot create a server socket at port " + port + ".", e);
+                       }
+               }
+               else {
+                       throw new GdxRuntimeException("Server socket protocol " + protocol + " is not supported under iOS backend.");
+               }
+       }
+
+       @Override
+       public Protocol getProtocol () {
+               return this.protocol;
+       }
+
+       @Override
+       public Socket accept (SocketHints hints) {
+               try {
+                       return new IOSSocket(listener.AcceptTcpClient(), hints);
+               }
+               catch (Exception e) {
+                       throw new GdxRuntimeException("Error accepting socket.", e);
+               }
+       }
+
+       @Override
+       public void dispose () {
+               if (listener != null) {
+                       try {
+                               listener.Stop();
+                               listener = null;
+                       }
+                       catch (Exception e) {
+                               throw new GdxRuntimeException("Error closing listener.", e);
+                       }
+               }
+       }
+}
diff --git a/backends/gdx-backend-iosmonotouch/src/com/badlogic/gdx/backends/ios/IOSSocket.java b/backends/gdx-backend-iosmonotouch/src/com/badlogic/gdx/backends/ios/IOSSocket.java
new file mode 100644 (file)
index 0000000..f5f5706
--- /dev/null
@@ -0,0 +1,118 @@
+package com.badlogic.gdx.backends.ios;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+
+import cli.System.Net.Sockets.LingerOption;
+import cli.System.Net.Sockets.NetworkStream;
+import cli.System.Net.Sockets.TcpClient;
+
+import com.badlogic.gdx.Net.Protocol;
+import com.badlogic.gdx.net.Socket;
+import com.badlogic.gdx.net.SocketHints;
+import com.badlogic.gdx.utils.GdxRuntimeException;
+
+/**
+ * The iOS socket implementation using System.Net.Sockets.TcpClient (Microsoft).
+ * 
+ * @author noblemaster
+ */
+public class IOSSocket implements Socket {
+
+       /** Our client or null for disposed, aka closed. */
+       private TcpClient client;
+       
+       private NetworkStream stream;
+       private IOSStreamInput inputStream;
+       private IOSStreamOutput outputStream;
+       
+       
+       public IOSSocket(Protocol protocol, String host, int port, SocketHints hints) {
+               if (protocol == Protocol.TCP) {
+                       try {
+                               // create and connect the socket
+                               // NOTE: there is no connection timeout setting available - will assume there is some sort of default!?
+                               client = new TcpClient(host, port);
+                               applyHints(hints);  // better to call BEFORE socket is connected!
+                               
+                               // create our streams!
+                               stream = client.GetStream();
+                               inputStream = new IOSStreamInput(stream, false);
+                               outputStream = new IOSStreamOutput(stream, false);
+                       }
+                       catch (Exception e) {
+                               throw new GdxRuntimeException("Error making a socket connection to " + host + ":" + port, e);
+                       }
+               }
+               else {
+                       throw new GdxRuntimeException("Socket protocol " + protocol + " is not supported under iOS backend.");
+               }
+       }
+       
+       public IOSSocket(TcpClient client, SocketHints hints) {
+               this.client = client;
+               applyHints(hints);
+       }
+       
+       private void applyHints(SocketHints hints) {
+               if (hints != null) {
+                       try {   
+                               // NOTE: traffic parameter settings/class cannot be set via iOS
+                               client.set_NoDelay(hints.tcpNoDelay);
+                               client.set_SendTimeout(hints.keepAlive ? 0 : 30000);  // milliseconds -> 0=no timeout
+                               client.set_SendBufferSize(hints.sendBufferSize);
+                               client.set_ReceiveTimeout(hints.keepAlive ? 0 : 30000);  // milliseconds -> 0=no timeout
+                               client.set_ReceiveBufferSize(hints.receiveBufferSize);
+                               client.set_LingerState(new LingerOption(hints.linger, hints.lingerDuration));
+                       }
+                       catch (Exception e) {
+                               throw new GdxRuntimeException("Error setting socket hints." , e);
+                       }
+               }
+       }
+       
+       @Override
+       public boolean isConnected () {
+               if (client != null) {
+                       return client.get_Connected();
+               }
+               else {
+                       return false;
+               }
+       }
+
+       @Override
+       public InputStream getInputStream () {
+               return inputStream;
+       }
+
+       @Override
+       public OutputStream getOutputStream () {
+               return outputStream;
+       }
+
+       @Override
+       public void dispose() {
+               if (client != null) {
+                       // close stream
+                       try {
+                               stream.Close();
+                       }
+                       catch (Exception e) {
+                               throw new GdxRuntimeException("Error closing stream.", e);
+                       }
+                       stream = null;
+                       
+                       // close connection
+                       try {
+                               client.Close();
+                               client.Dispose();
+                       }
+                       catch (Exception e) {
+                               throw new GdxRuntimeException("Error closing socket.", e);
+                       }
+                       client = null;
+               }
+       }
+}
diff --git a/backends/gdx-backend-iosmonotouch/src/com/badlogic/gdx/backends/ios/IOSStreamInput.java b/backends/gdx-backend-iosmonotouch/src/com/badlogic/gdx/backends/ios/IOSStreamInput.java
new file mode 100644 (file)
index 0000000..67b3149
--- /dev/null
@@ -0,0 +1,68 @@
+package com.badlogic.gdx.backends.ios;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import cli.System.IO.Stream;
+
+public class IOSStreamInput extends InputStream {
+
+       /** The stream for I/O operation. */
+       private Stream stream;
+       /** True if we can close the stream here. */
+       private boolean closeable;
+       
+       
+       public IOSStreamInput(Stream stream) {
+               this(stream, true);
+       }
+       
+       public IOSStreamInput(Stream stream, boolean closeable) {
+               this.stream = stream;
+               this.closeable = closeable;
+       }
+       
+       @Override
+       public int available () throws IOException {
+               // NOTE: not supported!
+               return 0;
+       }
+
+       @Override
+       public synchronized void mark (int readLimit) {
+               // not implemented
+       }
+
+       @Override
+       public boolean markSupported () {
+               return false;
+       }
+
+       @Override
+       public synchronized void reset () throws IOException {
+               // not implemented
+       }
+
+       @Override
+       public int read () throws IOException {
+               return stream.ReadByte();
+       }
+
+       @Override
+       public int read (byte[] b) throws IOException {
+               return read(b, 0, b.length);
+       }
+
+       @Override
+       public int read (byte[] b, int off, int len) throws IOException {
+               return stream.Read(b, off, len);
+       }
+
+       @Override
+       public void close () throws IOException {
+               if (closeable) {
+                       stream.Close();
+                       stream = null;
+               }
+       }
+}
diff --git a/backends/gdx-backend-iosmonotouch/src/com/badlogic/gdx/backends/ios/IOSStreamOutput.java b/backends/gdx-backend-iosmonotouch/src/com/badlogic/gdx/backends/ios/IOSStreamOutput.java
new file mode 100644 (file)
index 0000000..4ba152e
--- /dev/null
@@ -0,0 +1,53 @@
+package com.badlogic.gdx.backends.ios;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import cli.System.IO.Stream;
+
+public class IOSStreamOutput extends OutputStream {
+
+       /** The stream for I/O operation. */
+       private Stream stream;
+       /** True if we can close the stream here. */
+       private boolean closeable;
+       
+       
+       public IOSStreamOutput(Stream stream) {
+               this(stream, true);
+       }
+       
+       public IOSStreamOutput(Stream stream, boolean closeable) {
+               this.stream = stream;
+               this.closeable = closeable;
+       }
+
+       @Override
+       public void write (byte[] b) throws IOException {
+               write(b, 0, b.length);
+       }
+
+       @Override
+       public void write (byte[] b, int off, int len) throws IOException {
+               stream.Write(b, off, len);
+       }
+
+       @Override
+       public void write (int b) throws IOException {
+               stream.WriteByte((byte)(b & 0xff));
+       }
+       
+   @Override
+       public void flush () throws IOException {
+       // NOTE: has no effect on iOS!
+               stream.Flush();
+       }
+
+       @Override
+       public void close () throws IOException {
+               if (closeable) {
+                       stream.Close();
+                       stream = null;
+               }
+       }
+}