Многократное использование дескриптора сокета на сбое соединения

В моем клиентском коде я выполняю эти шаги для соединения с сокетом:

  1. Создание сокета

    sockDesc = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)  
    
  2. Соединение его (повторяют в течение 'x' времени в случае отказа),

    connect(sockDesc, (sockaddr *) &destAddr, sizeof(destAddr))  
    

    (После того, как заполнение destAddr поля)

  3. Используя сокет для send()/recv() операция:

    send(sockDesc, buffer, bufferLen, 0)  
    recv(sockDesc, buffer, bufferLen, 0)  
    
  4. close() дескриптор сокета и выход

    close(sockDesc)  
    

Если во время send()/recv() повреждения соединения, я нашел, что мог соединиться путем возврата к шагу 2.

Это решение хорошо? я должен закрыть дескриптор сокета и возвратиться к шагу 1?

Другое интересное наблюдение, что я не могу понять, состоит в том, когда я останавливаю свой сервер эха и запускаю клиент. Я создаю Сокет (шаг 1) и вызов connect() который перестал работать (как ожидалось), но затем я продолжаю звонить connect(), позволяет говорят, 10 раз. После 5 повторений я запускаю сервер и connect() успешно. Но во время send() звоните это получает SIGPIPE ошибка. Я хотел бы знать:

1) Сделайте я должен создать новый сокет каждый раз connect() сбои? Согласно моему пониманию, пока я не выполнил никого send()/recv() на сокете это совсем как ново, и я могу снова использовать то же fd для connect() звонить.

2) Я не понимаю почему SIGPIPE получен, когда сервер возрос и connect() успешно.

9
задан Barracuda 1 February 2015 в 12:53
поделиться

5 ответов

Поскольку Холст не имеет фиксированной ширины и высоты, я бы включил его в Поле просмотра :

<ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
        <Viewbox Stretch="Uniform">
            <Canvas x:Name="canvas" Background="DarkSeaGreen">
                <Canvas.LayoutTransform>
                <ScaleTransform ScaleY="-1" />
                </Canvas.LayoutTransform>
            </Canvas>
        </Viewbox>
    </ItemsPanelTemplate>
</ItemsControl.ItemsPanel>

Или поместите весь элемент управления UserControl в Поле просмотра .

-121--1683706-

Если вы хотите поддерживать больше браузеров, чем CSS3, вы можете посмотреть на библиотеку с открытым исходным кодом cufon javascript library

И вот API , если вы хотите сделать больше фанки вещи.

Major Pro: Позволяет делать то, что нужно.

Major Con: Запрещает выбор текста в некоторых браузерах, поэтому использование подходит для текстов заголовков (но вы можете использовать его на всем сайте, если хотите)

-121--998019-

Да, необходимо закрыть и вернуться к шагу 1:

close () закрывает дескриптор файла, чтобы оно больше не относилось ни к одному и может использоваться повторно.

Из здесь .

5
ответ дан 4 December 2019 в 12:18
поделиться

Гнезда, соответствующие нарушенному соединению, находятся в нестабильном состоянии. обычно повторное соединение невозможно, если операционная система не отпустит гнездо.

Я думаю, будет лучше закрыть() и подключиться снова... вам не придется создавать другой сокет.

В любом случае, убедитесь, что вы установили ЛИНГЕР вашего сокета, чтобы гарантировать, что при передаче не будут потеряны данные.

Смотрите http://www.gnu.org/s/libc/manual/html_node/Socket_002dLevel-Options.html#Socket_002dLevel-Options

4
ответ дан 4 December 2019 в 12:18
поделиться

Используйте сборку OpenJDK, известную для передачи TCK, чтобы минимизировать неожиданности.

-121--1266004-

Зумирование от RotateRight ( http://www.rotateright.com ) - это то, что я использовал. Она имеет вид бабочки функций, и вы можете дважды щелкнуть любую функцию, чтобы погрузиться в исходный или asm код. Создайте с помощью отладочной информации (-g), чтобы увидеть источник, но вы все равно должны построить и профилировать оптимизированный код.

-121--855344-

Если соединение разорвано и вы пытаетесь записать в дескриптор файла, вы должны получить ошибку/сигнал разрыва канала. Все это говорит о том, что дескриптор файла, который вы пытались записать, больше не имеет никого на другой стороне, чтобы прочитать то, что вы отправляете.

Что вы можете сделать, так это поймать сигнал SIGPIPE, а затем справиться с повторным подключением, закрыв FD и возвращаясь к шагу 1. Теперь у вас будет новый FD, из которого вы можете читать и писать для подключения.

2
ответ дан 4 December 2019 в 12:18
поделиться

Я думаю, что закрыть сокет - это правильно, несмотря на то, что это может сработать, если вы этого не сделаете.

Сокет, который не удалось подключиться, может быть не в ТОЧНО таком же состоянии, как новый, что может вызвать проблемы позже. Я бы предпочел избежать такой возможности и просто сделаю новую. Это чище.

Сокеты TCP содержат МНОГО состояний, некоторые из которых зависят от реализации и определяются сетью.

4
ответ дан 4 December 2019 в 12:18
поделиться

Способ состоит в использовании ~/.netrc, как описано на шаге 3 этой документации Git :

Затем добавьте следующее к $ HOME/.netrc (вы можете обойтись без, но будет предложено ввести пароль много раз):

 машина < имя _ сервера >
вход < имя _ пользователя >
пароль < пароль >

... и установить разрешения:

 chmod 600 ~/.netrc

ОБНОВЛЕНИЕ:

Как и в случае git 1,7,9, это, похоже, путь, чтобы пойти будет собственный API поддержки учетных данных. Git поставляется с открытым текстом хранилища учетных данных или менее удобным, но более безопасным временным кэшем учетных данных . Также можно использовать сторонних помощников по работе с учетными данными. На данный момент известно о помощнике для собственного хранилища учетных данных Windows и , который интегрируется с клавиатурой OS X . (Сборка Git, поставляемая Homebrew, имеет двоичный файл, как и другие дистрибутивы OS X Git. Github также предоставляет автономный двоичный .)

Как правило, достаточно настроить помощник учетных данных один раз:

git config --global credential.helper wincred

Или вместо wincred используйте любой помощник, подходящий для вашей платформы. (Если имя исполняемого файла помощника - git-credential-wincred , то значение параметра будет равно wincred и т.д.)

Помощники учетных данных также поддерживают необходимость иметь отдельные наборы учетных данных для различных репозиториев на одном хосте.

-121--961300-

Файлы cookie отправляются на сервер по каждому запросу, поэтому, если вы планируете сохранить значительный объем данных, сохраните их в сессии.

В противном случае, если вы храните небольшие объемы данных, файлы cookie будут в порядке.

Любые конфиденциальные данные должны храниться в сеансе, так как файлы cookie не защищены на 100%. Преимуществом файлов cookie является возможность сохранения памяти на сервере, который обычно хранит данные сеанса.

-121--999943-

Если в спецификации Single UNIX не говорится, что она ДОЛЖНА работать, чтобы вернуться к шагу # 2, а не к шагу # 1, то тот факт, что это происходит с работой в Linux, является лишь детализацией реализации, и вы были бы намного лучше и более портативны, если бы вы вернулись к шагу # 1. Насколько мне известно, спецификация не гарантирует, что можно вернуться к шагу № 2, и поэтому я бы посоветовал вернуться к шагу № 1.

2
ответ дан 4 December 2019 в 12:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: