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
\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
--- /dev/null
+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);
+ }
+ }
+ }
+}
--- /dev/null
+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;
+ }
+ }
+}
--- /dev/null
+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;
+ }
+ }
+}
--- /dev/null
+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;
+ }
+ }
+}