示例#1
0
        public TCPRawClient(IPAddress remote_ip, ushort remote_port, PacketCalculateEvent calc_event, int header_size, int maxPacketSize = 64 * 1024, int outputStreamMultiply = 64, LatencyMode mode = LatencyMode.Normal)
        {
            remoteIp       = remote_ip;
            remotePort     = remote_port;
            _maxPacketSize = maxPacketSize;
            this.mode      = mode;

            if (calc_event == null)
            {
                throw new ArgumentNullException(nameof(calc_event));
            }

            packetHeaderSize    = header_size;
            CalculatePacketSize = calc_event;
            workerStarted       = 0;
            _outputStream       = new ConcurrentMemoryStream(_maxPacketSize * outputStreamMultiply);
            rcvBuff             = new byte[maxPacketSize];
        }
        // Methods overidden from WebRequest

        public override WebResponse GetResponse()
        {
            ConcurrentMemoryStream stream = new ConcurrentMemoryStream()
            {
                Blocking    = true,
                ReadTimeout = Timeout
            };

            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            CancellationToken       cancellationToken       = cancellationTokenSource.Token;

            Task curlTask = Task.Factory.StartNew(() => {
                // We shouldn't need to check if libcurl is initialized, because it's reference counted and can be called multiple times.
                // However, repeated calls to curl_global_cleanup are crashing my program, so for the time being I'm not pairing it with this.
                // It's up the user to call curl_global_cleanup once when they're done using it.

                if (!LibCurl.IsInitialized) // Check so ref count will not be increased (only one call to curl_global_cleanup required after multiple requests)
                {
                    LibCurl.GlobalInit();
                }

                try {
                    using (CurlEasyHandle easyHandle = LibCurl.EasyInit())
                        using (SList headers = new SList())
                            using (MemoryStream postDataStream = new MemoryStream(GetRequestStream(validateMethod: false).ToArray())) {
                                CurlDataCopier dataCopier = new CurlDataCopier(stream, postDataStream, cancellationToken);

                                dataCopier.SetCallbacks(easyHandle);

                                LibCurl.EasySetOpt(easyHandle, CurlOption.Url, RequestUri.AbsoluteUri);
                                LibCurl.EasySetOpt(easyHandle, CurlOption.FollowLocation, AllowAutoRedirect ? 1 : 0);
                                LibCurl.EasySetOpt(easyHandle, CurlOption.MaxRedirs, MaximumAutomaticRedirections);
                                LibCurl.EasySetOpt(easyHandle, CurlOption.Timeout, Timeout);
                                LibCurl.EasySetOpt(easyHandle, CurlOption.HttpVersion, (int)GetHttpVersion());

                                if (AutomaticDecompression != DecompressionMethods.None)
                                {
                                    LibCurl.EasySetOpt(easyHandle, CurlOption.AcceptEncoding, GetAcceptEncoding());
                                }

                                LibCurl.EasySetOpt(easyHandle, CurlOption.TcpKeepAlive, KeepAlive ? 1 : 0);

                                if (File.Exists(LibCurl.CABundlePath))
                                {
                                    LibCurl.EasySetOpt(easyHandle, CurlOption.CaInfo, LibCurl.CABundlePath);
                                }

                                SetCookies(easyHandle);
                                SetCredentials(easyHandle);
                                SetHeaders(easyHandle, headers);
                                SetMethod(easyHandle);
                                SetProxy(easyHandle);

                                // Execute the request.

                                LibCurl.EasyPerform(easyHandle);
                            }
                }
                finally {
                    // Close the stream to indicate that we're done writing to it, unblocking readers.

                    stream.Close();

                    //LibCurl.GlobalCleanup();
                }
            }, cancellationToken);

            HaveResponse = true;

            return(new LibCurlHttpWebResponse(this, stream, cancellationTokenSource));
        }