как правильно запустить сокет (с какими опциями)?
От: mixa345  
Дата: 03.08.10 08:57
Оценка:
Здравствуйте,
надо переписать на с# linux демон, который ранее работал через xinetd в режиме socket_type = stream, wait = no (то есть под каждое входящее tcp соединение с данными xinetd пишет в stdin, демон в while определяет тип сообщения и пишет ответ в stdout)
клиентское приложение внешнее, исходников нет, есть только исходники демона-сервера, работать через снифер приходится
и есть возможность записать нормально работающий поток, потом попытаться повторить , рабочий поток выглядит так:

1) клиент: [SYN] Seq=0 Win=65535 Len=0 MSS=1460 WS=1
2) сервер: [SYN, ACK] Seq=0 Ack=1 Win=5840 Len=0 MSS=1380 WS=7
3) клиент: [ACK] Seq=1 Ack=1 Win=65536 Len=0
то есть нормально устанавливается соединение и затем циклично идут пакеты с данными
4) клиент: [PSH, ACK] Seq=1 Ack=1 Win=65536 Len=40
5) сервер: [ACK] Seq=1 Ack=41 Win=5888 Len=0
6) сервер: [PSH, ACK] Seq=1 Ack=41 Win=5888 Len=44
7) клиент: [ACK] Seq=41 Ack=45 Win=65492 Len=0
8) клиент: [PSH, ACK] Seq=41 Ack=45 Win=65492 Len=40
9) сервер: [PSH, ACK] Seq=45 Ack=81 Win=5888 Len=44
... и так далее, идет диалог без разрывов связи Seq и Ack увеличиваются

в моем случае, в С# версии сервера другая картина:
1) клиент [SYN] Seq=0 Win=65535 Len=0 MSS=1460
2) сервер [SYN, ACK] Seq=0 Ack=1 Win=8192 Len=0 MSS=1460
3) клиент [ACK] Seq=1 Ack=1 Win=65535 Len=0
4) клиент [FIN, ACK] Seq=1 Ack=1 Win=65535 Len=0 —
то есть клиент почему-то разрывает соединение, вся разница в пакетах рукопожатия, то что в рабочей версии есть WS, а в моей нет
затем снова начинается рукопожатие, но в следующий раз уже мой сервер посылает Fin, и так чередуется — то клиент, то сервер ресетят соединение,
сообщения с данными доходят и клиент их получает, но через раз)) — в этом проблема, между ними каждый раз заново устанавливается новое соединение

собственно коммуникация осуществляется сообщениями, на которые надо отвечать мгновенно без наполнения буфера,
но это вроде работает — клиент делает запрос с PSH и сервер ему отвечает с PSH

в чем может быть причина такого поведения?, вероятно сокеты не так запускаю, подскажите пожалуйста что поправить:


IPEndPoint localEndPoint = new IPEndPoint(ipAddress, port);
listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listener.Bind(localEndPoint);
listener.Listen(200);
while (true)
{
    Socket clientSocket = listener.Accept();
    byte[] buffer = new byte[BUF_SIZE];
    int k = clientSocket.Receive(buffer);
    Int16 type = BitConverter.ToInt16(buffer, 2);
    //сообщения разных типов, в зависимости от типа потом case отвечает по сlientSocket                  
    switch (type)
    {
        case 0x0010:
        ...
        case 0x0011:
        sendBuf = new byte[Reply11];
        Init(sendBuf);
        try
                {
             clientSocket.Send(sendBuf, sendBuf.Length, 0);
            clientSocket.Shutdown(SocketShutdown.Both);
            clientSocket.Close();
                }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }         
}


собственно вопросов два : первый наверно нубский 1) в моем случае clientSocket я закрываю, но судя по снифу рабочего процесса, его keepAlive как-то сделать надо, чтобы многократно на нем делать recv() и send() (или keepAlive на уровне listener сохраняется и для каждого нового сообщения надо создавать новый clientSocket и затем его закрывать?), и 2) почему в C# версии сервера клиент первым посылает Fin ?, ведь если на нем keepAlive какой-то, а у меня -нет, я должен первым Fin послать ?
сокет keepalive
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.