blob: 524003eb2b3736baba4f19bbe75209bca0b6021d [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;
Jens Geyer018c1b82015-04-17 20:55:05 +020026using System.Reflection;
David Reiss7f42bcf2008-01-11 20:59:12 +000027
28
29namespace Thrift.Transport
30{
Jens Geyerd5436f52014-10-03 19:50:38 +020031 public class TServerSocket : TServerTransport
32 {
33 /**
34 * Underlying server with socket
35 */
36 private TcpListener server = null;
David Reiss7f42bcf2008-01-11 20:59:12 +000037
Jens Geyerd5436f52014-10-03 19:50:38 +020038 /**
39 * Port to listen on
40 */
41 private int port = 0;
David Reiss7f42bcf2008-01-11 20:59:12 +000042
Jens Geyerd5436f52014-10-03 19:50:38 +020043 /**
44 * Timeout for client sockets from accept
45 */
46 private int clientTimeout = 0;
David Reiss7f42bcf2008-01-11 20:59:12 +000047
Jens Geyerd5436f52014-10-03 19:50:38 +020048 /**
49 * Whether or not to wrap new TSocket connections in buffers
50 */
51 private bool useBufferedSockets = false;
David Reiss63191332009-01-06 19:49:22 +000052
Jens Geyerd5436f52014-10-03 19:50:38 +020053 /**
54 * Creates a server socket from underlying socket object
55 */
56 public TServerSocket(TcpListener listener)
Jens Geyer018c1b82015-04-17 20:55:05 +020057 : this(listener, 0)
Jens Geyerd5436f52014-10-03 19:50:38 +020058 {
59 }
David Reiss7f42bcf2008-01-11 20:59:12 +000060
Jens Geyerd5436f52014-10-03 19:50:38 +020061 /**
62 * Creates a server socket from underlying socket object
63 */
64 public TServerSocket(TcpListener listener, int clientTimeout)
65 {
66 this.server = listener;
67 this.clientTimeout = clientTimeout;
68 }
David Reiss7f42bcf2008-01-11 20:59:12 +000069
Jens Geyerd5436f52014-10-03 19:50:38 +020070 /**
71 * Creates just a port listening server socket
72 */
73 public TServerSocket(int port)
74 : this(port, 0)
75 {
76 }
David Reiss7f42bcf2008-01-11 20:59:12 +000077
Jens Geyerd5436f52014-10-03 19:50:38 +020078 /**
79 * Creates just a port listening server socket
80 */
81 public TServerSocket(int port, int clientTimeout)
Jens Geyer018c1b82015-04-17 20:55:05 +020082 : this(port, clientTimeout, false)
Jens Geyerd5436f52014-10-03 19:50:38 +020083 {
84 }
David Reiss63191332009-01-06 19:49:22 +000085
Jens Geyerd5436f52014-10-03 19:50:38 +020086 public TServerSocket(int port, int clientTimeout, bool useBufferedSockets)
87 {
88 this.port = port;
89 this.clientTimeout = clientTimeout;
90 this.useBufferedSockets = useBufferedSockets;
91 try
92 {
93 // Make server socket
Jens Geyer018c1b82015-04-17 20:55:05 +020094 this.server = TSocketVersionizer.CreateTcpListener(port);
95 this.server.Server.NoDelay = true;
Jens Geyerd5436f52014-10-03 19:50:38 +020096 }
97 catch (Exception)
98 {
99 server = null;
100 throw new TTransportException("Could not create ServerSocket on port " + port + ".");
101 }
102 }
David Reiss7f42bcf2008-01-11 20:59:12 +0000103
Jens Geyerd5436f52014-10-03 19:50:38 +0200104 public override void Listen()
105 {
106 // Make sure not to block on accept
107 if (server != null)
108 {
109 try
110 {
111 server.Start();
112 }
113 catch (SocketException sx)
114 {
115 throw new TTransportException("Could not accept on listening socket: " + sx.Message);
116 }
117 }
118 }
David Reiss7f42bcf2008-01-11 20:59:12 +0000119
Jens Geyer102bca42013-06-25 22:21:29 +0200120 protected override TTransport AcceptImpl()
Roger Meierb1ec4cc2012-04-11 21:21:41 +0000121 {
Jens Geyer102bca42013-06-25 22:21:29 +0200122 if (server == null)
123 {
124 throw new TTransportException(TTransportException.ExceptionType.NotOpen, "No underlying server socket.");
125 }
126 try
127 {
128 TSocket result2 = null;
129 TcpClient result = server.AcceptTcpClient();
130 try
131 {
132 result2 = new TSocket(result);
133 result2.Timeout = clientTimeout;
134 if (useBufferedSockets)
135 {
136 TBufferedTransport result3 = new TBufferedTransport(result2);
137 return result3;
138 }
139 else
140 {
141 return result2;
142 }
143 }
144 catch (System.Exception)
145 {
Jens Geyerd5436f52014-10-03 19:50:38 +0200146 // If a TSocket was successfully created, then let
Jens Geyer102bca42013-06-25 22:21:29 +0200147 // it do proper cleanup of the TcpClient object.
148 if (result2 != null)
149 result2.Dispose();
150 else // Otherwise, clean it up ourselves.
151 ((IDisposable)result).Dispose();
152 throw;
153 }
154 }
155 catch (Exception ex)
156 {
157 throw new TTransportException(ex.ToString());
158 }
Roger Meierb1ec4cc2012-04-11 21:21:41 +0000159 }
David Reiss7f42bcf2008-01-11 20:59:12 +0000160
Jens Geyer102bca42013-06-25 22:21:29 +0200161 public override void Close()
Jens Geyerd5436f52014-10-03 19:50:38 +0200162 {
163 if (server != null)
164 {
165 try
166 {
167 server.Stop();
168 }
169 catch (Exception ex)
170 {
171 throw new TTransportException("WARNING: Could not close server socket: " + ex);
172 }
173 server = null;
174 }
175 }
176 }
David Reiss7f42bcf2008-01-11 20:59:12 +0000177}