Мне нужен приведенный ниже код для отправки FIN/ACK после завершения связи с сервером. Я использовал сокеты раньше, и вы прямо указываете ему закрыть соединение, после чего сетевая карта отправляет FIN/ACK. Здесь у меня нет такого контроля, и мне любопытно, есть ли способ заставить FIN / ACK. Когда я завершаю программу, отправляется FIN/ACK.
Я попытался разобрать объект, который поддерживает TCP-соединение открытым, но не уверен, что он работает правильно. Я попытался поместить его в свой собственный поток и установить для него значение void.
Чтобы запустить этот код в Visual Studio, вам нужно добавить ссылку на сервер (https://www.onvif.org/ver10/device/wsdl/devicemgmt.wsdl) и назовите его 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//////////////////////////
}
}
}
Еще одна мысль: если бы я мог выяснить, на каком порту было открыто это TCP-соединение, я мог бы вручную создать строку для отправки FIN/ACK на этот порт.
Как рекомендуется ниже, я попытался использовать. Возможно, я делаю это неправильно: сначала я переместил свою функцию, которая создает TCP-соединение, в общедоступный класс, и этот класс наследовался от IDisposable.
Функция класса....
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;
}
}
}
Затем в основной части кода экземпляр был заключен в оператор using...
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);
}
}
Тем не менее соединение TCP оставалось открытым, пока приложение не было закрыто.
Shutdown()
, на более высоких уровнях API вам может потребоваться просто удалить объект или использовать какой-либо механизм, который должен отключить соединение. - person Peter Duniho   schedule 24.01.2021