Пример #1
0
		static void BeginSendToCallback (SocketAsyncResult sockares, int sent_so_far)
		{
			int total = 0;
			try {
				total = sockares.socket.SendTo_nochecks (sockares.Buffer, sockares.Offset, sockares.Size, sockares.SockFlags, sockares.EndPoint);

				if (sockares.error == 0) {
					sent_so_far += total;
					sockares.Offset += total;
					sockares.Size -= total;
				}

				if (sockares.Size > 0) {
					IOSelector.Add (sockares.Handle, new IOSelectorJob (IOOperation.Write, s => BeginSendToCallback ((SocketAsyncResult) s, sent_so_far), sockares));
					return; // Have to finish writing everything. See bug #74475.
				}

				sockares.Total = sent_so_far;
			} catch (Exception e) {
				sockares.Complete (e);
				return;
			}

			sockares.Complete ();
		}
Пример #2
0
		public IAsyncResult BeginConnect (EndPoint end_point, AsyncCallback callback, object state)
		{
			ThrowIfDisposedAndClosed ();

			if (end_point == null)
				throw new ArgumentNullException ("end_point");

			SocketAsyncResult sockares = new SocketAsyncResult (this, callback, state, SocketOperation.Connect) {
				EndPoint = end_point,
			};

			// Bug #75154: Connect() should not succeed for .Any addresses.
			if (end_point is IPEndPoint) {
				IPEndPoint ep = (IPEndPoint) end_point;
				if (ep.Address.Equals (IPAddress.Any) || ep.Address.Equals (IPAddress.IPv6Any)) {
					sockares.Complete (new SocketException ((int) SocketError.AddressNotAvailable), true);
					return sockares;
				}
			}

			int error = 0;

			if (connect_in_progress) {
				// This could happen when multiple IPs are used
				// Calling connect() again will reset the connection attempt and cause
				// an error. Better to just close the socket and move on.
				connect_in_progress = false;
				safe_handle.Dispose ();
				safe_handle = new SafeSocketHandle (Socket_internal (address_family, socket_type, protocol_type, out error), true);
				if (error != 0)
					throw new SocketException (error);
			}

			bool blk = is_blocking;
			if (blk)
				Blocking = false;
			Connect_internal (safe_handle, end_point.Serialize (), out error);
			if (blk)
				Blocking = true;

			if (error == 0) {
				// succeeded synch
				is_connected = true;
				is_bound = true;
				sockares.Complete (true);
				return sockares;
			}

			if (error != (int) SocketError.InProgress && error != (int) SocketError.WouldBlock) {
				// error synch
				is_connected = false;
				is_bound = false;
				sockares.Complete (new SocketException (error), true);
				return sockares;
			}

			// continue asynch
			is_connected = false;
			is_bound = false;
			connect_in_progress = true;

			IOSelector.Add (sockares.Handle, new IOSelectorJob (IOOperation.Write, BeginConnectCallback, sockares));

			return sockares;
		}
Пример #3
0
		public IAsyncResult BeginConnect(EndPoint end_point,
						 AsyncCallback callback,
						 object state) {

			if (disposed && closed)
				throw new ObjectDisposedException (GetType ().ToString ());

			if (end_point == null)
				throw new ArgumentNullException ("end_point");

			SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Connect);
			req.EndPoint = end_point;

			// Bug #75154: Connect() should not succeed for .Any addresses.
			if (end_point is IPEndPoint) {
				IPEndPoint ep = (IPEndPoint) end_point;
				if (ep.Address.Equals (IPAddress.Any) || ep.Address.Equals (IPAddress.IPv6Any)) {
					req.Complete (new SocketException ((int) SocketError.AddressNotAvailable), true);
					return req;
				}
			}

			int error = 0;
			if (!blocking) {
				SocketAddress serial = end_point.Serialize ();
				Connect_internal (socket, serial, out error);
				if (error == 0) {
					// succeeded synch
					connected = true;
					req.Complete (true);
				} else if (error != (int) SocketError.InProgress && error != (int) SocketError.WouldBlock) {
					// error synch
					connected = false;
					req.Complete (new SocketException (error), true);
				}
			}

			if (blocking || error == (int) SocketError.InProgress || error == (int) SocketError.WouldBlock) {
				// continue asynch
				connected = false;
				Worker worker = new Worker (req);
				SocketAsyncCall sac = new SocketAsyncCall (worker.Connect);
				sac.BeginInvoke (null, req);
			}

			return(req);
		}
Пример #4
0
		IAsyncResult BeginConnect(EndPoint end_point, AsyncCallback callback, object state)
		{
			if (disposed && closed)
				throw new ObjectDisposedException (GetType ().ToString ());

			if (end_point == null)
				throw new ArgumentNullException ("end_point");

			SocketAsyncResult req = new SocketAsyncResult (this, state, callback, SocketOperation.Connect);
			req.EndPoint = end_point;

			// Bug #75154: Connect() should not succeed for .Any addresses.
			if (end_point is IPEndPoint) {
				IPEndPoint ep = (IPEndPoint) end_point;
				if (ep.Address.Equals (IPAddress.Any) || ep.Address.Equals (IPAddress.IPv6Any)) {
					req.Complete (new SocketException ((int) SocketError.AddressNotAvailable), true);
					return req;
				}
			}

			int error = 0;
			if (connect_in_progress) {
				// This could happen when multiple IPs are used
				// Calling connect() again will reset the connection attempt and cause
				// an error. Better to just close the socket and move on.
				connect_in_progress = false;
				Close_internal (socket, out error);
				socket = Socket_internal (address_family, socket_type, protocol_type, out error);
				if (error != 0)
					throw new SocketException (error);
			}
			bool blk = blocking;
			if (blk)
				Blocking = false;
			SocketAddress serial = end_point.Serialize ();
			Connect_internal (socket, serial, out error);
			if (blk)
				Blocking = true;
			if (error == 0) {
				// succeeded synch
				connected = true;
				isbound = true;
				req.Complete (true);
				return req;
			}

			if (error != (int) SocketError.InProgress && error != (int) SocketError.WouldBlock) {
				// error synch
				connected = false;
				isbound = false;
				req.Complete (new SocketException (error), true);
				return req;
			}

			// continue asynch
			connected = false;
			isbound = false;
			connect_in_progress = true;
			socket_pool_queue (Worker.Dispatcher, req);
			return req;
		}
Пример #5
0
		static void BeginSendCallback (SocketAsyncResult sockares, int sent_so_far)
		{
			int total = 0;

			try {
				total = Socket.Send_internal (sockares.socket.safe_handle, sockares.Buffer, sockares.Offset, sockares.Size, sockares.SockFlags, out sockares.error);
			} catch (Exception e) {
				sockares.Complete (e);
				return;
			}

			if (sockares.error == 0) {
				sent_so_far += total;
				sockares.Offset += total;
				sockares.Size -= total;

				if (sockares.socket.is_disposed) {
					sockares.Complete (total);
					return;
				}

				if (sockares.Size > 0) {
					IOSelector.Add (sockares.handle, new IOSelectorJob (IOOperation.Write, s => BeginSendCallback ((SocketAsyncResult) s, sent_so_far), sockares));
					return; // Have to finish writing everything. See bug #74475.
				}

				sockares.Total = sent_so_far;
			}

			sockares.Complete (total);
		}