blob: 82a367c2647ded56d952a6cfe7fe7b961f79eb88 [file] [log] [blame]
Kevin Clarkab4460d2009-03-20 02:28:41 +00001/**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
Todd Lipcon53ae9f32009-12-07 00:42:38 +000018 *
19 * Contains some contributions under the Thrift Software License.
20 * Please see doc/old-thrift-license.txt in the Thrift distribution for
21 * details.
Kevin Clarkab4460d2009-03-20 02:28:41 +000022 */
David Reiss7f42bcf2008-01-11 20:59:12 +000023
24using System;
David Reiss7f42bcf2008-01-11 20:59:12 +000025using System.Net.Sockets;
26
27
28namespace Thrift.Transport
29{
Jens Geyerd5436f52014-10-03 19:50:38 +020030 public class TServerSocket : TServerTransport
31 {
32 /**
33 * Underlying server with socket
34 */
35 private TcpListener server = null;
David Reiss7f42bcf2008-01-11 20:59:12 +000036
Jens Geyerd5436f52014-10-03 19:50:38 +020037 /**
38 * Port to listen on
39 */
40 private int port = 0;
David Reiss7f42bcf2008-01-11 20:59:12 +000041
Jens Geyerd5436f52014-10-03 19:50:38 +020042 /**
43 * Timeout for client sockets from accept
44 */
45 private int clientTimeout = 0;
David Reiss7f42bcf2008-01-11 20:59:12 +000046
Jens Geyerd5436f52014-10-03 19:50:38 +020047 /**
48 * Whether or not to wrap new TSocket connections in buffers
49 */
50 private bool useBufferedSockets = false;
David Reiss63191332009-01-06 19:49:22 +000051
Jens Geyerd5436f52014-10-03 19:50:38 +020052 /**
53 * Creates a server socket from underlying socket object
54 */
55 public TServerSocket(TcpListener listener)
Jens Geyer95717c92015-04-23 22:48:13 +020056 :this(listener, 0)
Jens Geyerd5436f52014-10-03 19:50:38 +020057 {
58 }
David Reiss7f42bcf2008-01-11 20:59:12 +000059
Jens Geyerd5436f52014-10-03 19:50:38 +020060 /**
61 * Creates a server socket from underlying socket object
62 */
63 public TServerSocket(TcpListener listener, int clientTimeout)
64 {
65 this.server = listener;
66 this.clientTimeout = clientTimeout;
67 }
David Reiss7f42bcf2008-01-11 20:59:12 +000068
Jens Geyerd5436f52014-10-03 19:50:38 +020069 /**
70 * Creates just a port listening server socket
71 */
72 public TServerSocket(int port)
73 : this(port, 0)
74 {
75 }
David Reiss7f42bcf2008-01-11 20:59:12 +000076
Jens Geyerd5436f52014-10-03 19:50:38 +020077 /**
78 * Creates just a port listening server socket
79 */
80 public TServerSocket(int port, int clientTimeout)
Jens Geyer95717c92015-04-23 22:48:13 +020081 :this(port, clientTimeout, false)
Jens Geyerd5436f52014-10-03 19:50:38 +020082 {
83 }
David Reiss63191332009-01-06 19:49:22 +000084
Jens Geyerd5436f52014-10-03 19:50:38 +020085 public TServerSocket(int port, int clientTimeout, bool useBufferedSockets)
86 {
87 this.port = port;
88 this.clientTimeout = clientTimeout;
89 this.useBufferedSockets = useBufferedSockets;
90 try
91 {
92 // Make server socket
Jens Geyer95717c92015-04-23 22:48:13 +020093 server = new TcpListener(System.Net.IPAddress.Any, this.port);
94 server.Server.NoDelay = true;
Jens Geyerd5436f52014-10-03 19:50:38 +020095 }
96 catch (Exception)
97 {
98 server = null;
99 throw new TTransportException("Could not create ServerSocket on port " + port + ".");
100 }
101 }
David Reiss7f42bcf2008-01-11 20:59:12 +0000102
Jens Geyerd5436f52014-10-03 19:50:38 +0200103 public override void Listen()
104 {
105 // Make sure not to block on accept
106 if (server != null)
107 {
108 try
109 {
110 server.Start();
111 }
112 catch (SocketException sx)
113 {
114 throw new TTransportException("Could not accept on listening socket: " + sx.Message);
115 }
116 }
117 }
David Reiss7f42bcf2008-01-11 20:59:12 +0000118
Jens Geyer102bca42013-06-25 22:21:29 +0200119 protected override TTransport AcceptImpl()
Roger Meierb1ec4cc2012-04-11 21:21:41 +0000120 {
Jens Geyer102bca42013-06-25 22:21:29 +0200121 if (server == null)
122 {
123 throw new TTransportException(TTransportException.ExceptionType.NotOpen, "No underlying server socket.");
124 }
125 try
126 {
127 TSocket result2 = null;
128 TcpClient result = server.AcceptTcpClient();
129 try
130 {
131 result2 = new TSocket(result);
132 result2.Timeout = clientTimeout;
133 if (useBufferedSockets)
134 {
135 TBufferedTransport result3 = new TBufferedTransport(result2);
136 return result3;
137 }
138 else
139 {
140 return result2;
141 }
142 }
143 catch (System.Exception)
144 {
Jens Geyerd5436f52014-10-03 19:50:38 +0200145 // If a TSocket was successfully created, then let
Jens Geyer102bca42013-06-25 22:21:29 +0200146 // it do proper cleanup of the TcpClient object.
147 if (result2 != null)
148 result2.Dispose();
149 else // Otherwise, clean it up ourselves.
150 ((IDisposable)result).Dispose();
151 throw;
152 }
153 }
154 catch (Exception ex)
155 {
156 throw new TTransportException(ex.ToString());
157 }
Roger Meierb1ec4cc2012-04-11 21:21:41 +0000158 }
David Reiss7f42bcf2008-01-11 20:59:12 +0000159
Jens Geyer102bca42013-06-25 22:21:29 +0200160 public override void Close()
Jens Geyerd5436f52014-10-03 19:50:38 +0200161 {
162 if (server != null)
163 {
164 try
165 {
166 server.Stop();
167 }
168 catch (Exception ex)
169 {
170 throw new TTransportException("WARNING: Could not close server socket: " + ex);
171 }
172 server = null;
173 }
174 }
175 }
David Reiss7f42bcf2008-01-11 20:59:12 +0000176}