У нас есть служба Windows, которая успешно работает уже более года.Совсем недавно это стало доставлять неприятности.У меня нет опыта программирования сокетов, но я должен попытаться найти причину проблемы - отлично!
Служба установлена на центральном сервере.Он «прослушивает» данные, поступающие с примерно 400 серверов, расположенных в магазинах по всей стране.
При запуске служба получает список хранилищ, из которых необходимо собирать данные, а также IP-адрес сервера хранилища.Затем он перебирает список и выполняет следующий код:
IPEndPoint lep = new IPEndPoint(lipa.AddressList[lipa.AddressList.GetUpperBound(0)], (int)portNumber);
PosListener posListener = new PosListener(lep,this.pendingBacklog,storeTable,messageList);
Конструктор для PosListner выглядит следующим образом:
internal PosListener(IPEndPoint lep, int pendingBacklog, Hashtable storeTable, ArrayList messageList) : base(lep.Address.AddressFamily,SocketType.Stream,ProtocolType.Tcp)
{
ITraceState trState = PosApplication.Trace.StartProc("PosListener");
try
{
// Setup listener
this.ngcIPAddress = lep.Address.ToString();
this.ngcPort = lep.Port;
this.storeTable = storeTable;
this.storeLock = new ReaderWriterLock();
this.messageList = messageList;
this.messageLock = new ReaderWriterLock();
this.handlerList = new ArrayList();
this.handlerLock = new ReaderWriterLock();
this.asyncCallback = new AsyncCallback(this.CallbackAccept);
this.Bind(lep);
this.Listen(pendingBacklog);
// Start listening
PosApplication.PosSocketsEventLog.WriteEntry("Starting Listener on NGC Port "+this.ngcIPAddress+":"+this.ngcPort);
PosApplication.Trace.WriteDebug("Starting Listener on NGC Port "+this.ngcIPAddress+":"+this.ngcPort);
this.BeginAccept(this.asyncCallback,null);
}
catch (Exception e)
{
ExceptionManager.Publish(e);
}
finally
{
trState.EndProc();
}
}
Насколько я понимаю, конструктор регистрирует метод CallbackAccept длябудет выполняться всякий раз, когда обнаруживается трафик в отслеживаемом сокете.
Этот метод обратного вызова вставляется ниже:
private void CallbackAccept(IAsyncResult ar)
{
ITraceState trState = PosApplication.Trace.StartProc("CallbackAccept");
try
{
// Get the socket that handles the client connection
Socket connection = this.EndAccept(ar);
// Start listening for the next client connection
this.BeginAccept(this.asyncCallback,null);
string storeIPAddress = ((IPEndPoint)connection.RemoteEndPoint).Address.ToString();
int storePort = ((IPEndPoint)connection.RemoteEndPoint).Port;
PosApplication.Trace.WriteDebug("Listener "+this.ngcIPAddress+":"+this.ngcPort+" received connection request from "+storeIPAddress+":"+storePort);
// Check the remote end point has a recognised Store IP Address
this.storeLock.AcquireReaderLock(-1);
bool isAcceptable;
try
{
isAcceptable = this.storeTable.Contains(storeIPAddress);
}
finally
{
this.storeLock.ReleaseReaderLock();
}
// Close connection and throw exception if the remote end point
// does not have a recognised Store IP Address
if (!isAcceptable)
{
connection.Shutdown(SocketShutdown.Both);
connection.Close();
CrmServiceException ce = new CrmServiceException(
"Client",
"ConfigurationError",
"PosSocketsService.UnSupportedStoreIPAddress",
PosApplication.Trace,
this.ngcIPAddress,
this.ngcPort.ToString(),
storeIPAddress,
storePort.ToString());
throw ce;
}
// Setup a connection handler
this.handlerLock.AcquireWriterLock(-1);
try
{
IPosHandler posHandler = PosApplication.ConstructIPosHandler(this,connection);
this.handlerList.Add(posHandler);
}
finally
{
this.handlerLock.ReleaseWriterLock();
}
}
catch (ObjectDisposedException)
{
// this object has been disposed by another thread
}
catch (SocketException e)
{
ExceptionManager.Publish(e);
PosApplication.Trace.WriteDebug("Unexpected Socket Exception Closing Listener "+this.ngcIPAddress+":"+this.ngcPort);
this.Dispose();
}
catch (Exception e)
{
ExceptionManager.Publish(e);
}
finally
{
trState.EndProc();
}
}
Подробности исключения приведены ниже:
Тип исключения: System.Net.Sockets.SocketException
ErrorCode: 10054
Сообщение: существующее соединение было принудительно закрыто удаленным хостом
SocketErrorCode: ConnectionReset
NativeErrorCode: 10054
Данные: System.Collections.ListDictionaryInternal
TargetSite: System.Net.Sockets.Socket EndAccept (Byte [] ByRef, Int32 ByRef,System.IAsyncResult)
HelpLink: NULL
Источник: система
Информация StackTrace
на System.Net.Sockets.Socket.EndAccept (Byte [] & buffer, Int32 & bytesTransferred, IAsyncResult asyncResult)
в System.Net.Sockets.Socket.EndAccept (IAsyncResult asyncResult)
в Fujitsu.eockerSerSerSerSerSer..CallbackAccept (IAsyncResult ar) в C: \ Inetpub \ wwwroot \ PosSocketsService \ PosListener.cs: строка 109
Строка 109 выглядит следующим образом:
Socket connection = this.EndAccept(ar);
Поведение, которое мы 'Мы видим, что все POSListner запускаются при запуске службы.Затем через короткий промежуток времени каждый из них закрывается - с тем же повышением 10054.
Кажется, что слушатель вызван данными, появляющимися на контролируемом порте, но когда метод обратного вызова пытается создать сокет, такчто данные читаются - windows не может установить сокет.
Может кто-нибудь предложить, какие шаги можно предпринять, чтобы попытаться определить причину проблемы?