Need to send FIN/ACK

Viewed 136

I need the code below to send a FIN/ACK when it has completed communicating with the server. I've used sockets before and you explicitly tell it to close the connection at which point the NIC sends the FIN/ACK. Here I don't have that kind of control and am curious if there is a way to force the FIN/ACK. When I terminate the program a FIN/ACK is sent.

I've tried deconstructing the object that is keeping the TCP connection open but am not confident it working correctly. I've tried putting it on its own thread, and setting it to void.

To run this code in visual studio you will need to add a Server Reference (https://www.onvif.org/ver10/device/wsdl/devicemgmt.wsdl) and call it "Onvif_Video_Player."

using System;
using System.Text;
using System.Windows.Forms;
using Onvif_Video_Player.OnvifDevice;
using System.ServiceModel.Channels;
using System.ServiceModel;


namespace Onvif_Video_Player
{
    public partial class Form1 : Form
    {
        //Form1 Interactive Objecst 
        string IPAddress;
        String userName;
        string password;

        public Form1()
        {
            InitializeComponent();
        }

        private void GetProfiles_Click(object sender, EventArgs e)
        {
            IPAddress = txtbox_IPAddress.Text;
            userName = TxtBox_UserName.Text;
            password = TxtBox_Password.Text;
            GetOnvifProfiles();
            while (true)
            {
             //Do other stuff 
            }
        }

        private void GetOnvifProfiles()
        {
                UriBuilder deviceUri;
                System.ServiceModel.Channels.CustomBinding binding;

                deviceUri = new UriBuilder("Http:/onvif/device_service");

                HttpTransportBindingElement httpTransport = new HttpTransportBindingElement();
                httpTransport.AuthenticationScheme = System.Net.AuthenticationSchemes.Digest;
                deviceUri.Host = IPAddress;
                var messageElement = new TextMessageEncodingBindingElement();
                messageElement.MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.None);
                System.ServiceModel.Channels.CustomBinding customBinding = new System.ServiceModel.Channels.CustomBinding(messageElement, httpTransport);
                binding = new System.ServiceModel.Channels.CustomBinding(new TextMessageEncodingBindingElement(MessageVersion.Soap12, Encoding.UTF8), httpTransport);
                DeviceClient Onvif_Device = new DeviceClient(binding, new EndpointAddress(deviceUri.ToString()));
                OnvifDevice.Service[] service = Onvif_Device.GetServices(false);
                ///////////////////////////Send FIN/ACK//////////////////////////
            }
        }
    }

Another thought would be if I could figure out what port this TCP connection was opened on, I could manually construct a string to send a FIN/ACK on that port.

As recommend below, I tried using. Maybe I'm doing it incorrectly: I first moved my function that creates the TCP connection to a public class and had that class inherit from IDisposable.

Class function....

namespace Onvif_Video_Player
    {
        public class CustomBindingsAndClients : IDisposable
        {
            void IDisposable.Dispose() 
            {
                int i = 0;
            }
    
            public void GetProfiles(string IP, string IuserName, string password)
            {
                UriBuilder deviceUri = new UriBuilder("Http:/onvif/device_service");
                System.ServiceModel.Channels.CustomBinding binding;
                HttpTransportBindingElement httpTransport = new HttpTransportBindingElement();
                httpTransport.AuthenticationScheme = System.Net.AuthenticationSchemes.Digest;
                deviceUri.Host = "192.168.1.65";
                var messageElement = new TextMessageEncodingBindingElement();
                messageElement.MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.None);
                System.ServiceModel.Channels.CustomBinding customBinding = new System.ServiceModel.Channels.CustomBinding(messageElement, httpTransport);
                binding = new System.ServiceModel.Channels.CustomBinding(new TextMessageEncodingBindingElement(MessageVersion.Soap12, Encoding.UTF8), httpTransport);
                DeviceClient Onvif_Device = new DeviceClient(binding, new EndpointAddress(deviceUri.ToString()));
                OnvifDevice.Service[] service = Onvif_Device.GetServices(true);
                binding = null;
            }
        }
    }

Then in the main body of the code wrapped the instance in a using statement...

        private void GetProfiles_Click(object sender, EventArgs e)
    {
        IPAddress = txtbox_IPAddress.Text;
        userName = TxtBox_UserName.Text;
        password = TxtBox_Password.Text;
        using (CustomBindingsAndClients TEMP = new CustomBindingsAndClients()) 
        {
            TEMP.GetProfiles(IPAddress, userName, password);
        }
     }

Still the TCP connect stayed open until the application was closed.

0 Answers
Related