Книга: Программирование мобильных устройств на платформе .NET Compact Framework
Листинг 15.5. Класс IrDAFileReceive
Листинг 15.5. Класс IrDAFileReceive
'-------------------------------------------------------------------
'Обеспечивает прием файла через IrDA (инфракрасный порт)
'Этот класс НЕ является реентерабельным и не должен вызываться более
'чем одной функцией за один раз. Если необходимо иметь несколько
'сеансов связи через IR, это необходимо делать путем создания
'нескольких различных экземпляров данного класса.
'--------------------------------------------------------------------
Public Class IrDAFileReceive
Private m_wasListenerStopped As Boolean
Private m_IrDAServiceName As String
Private m_fileNameForDownload As String
Private m_errorDurmgTransfer As String
Private m_irListener As System.Net.Sockets.IrDAListener
Private m ReceiveStatus As ReceiveStatus
Public ReadOnly Property ErrorText() As String
Get
Return m_errorDuringTransfer
End Get
End Property
'--------------------------
'Различные состояния приема
'--------------------------
Public Enum ReceiveStatus
NotDone_SettingUp
NotDone_WaitingForSender
NotDone_Receiving
Done_Success
Done_Aborted
Done_ErrorOccured
End Enum
'------------------------------
' Возвращает состояние передачи
'------------------------------
Public ReadOnly Property Status() As ReceiveStatus
Get
SyncLock (Me)
Return m_ReceiveStatus
End SyncLock
End Get
End Property
Private Sub setStatus(ByVal newStatus As ReceiveStatus)
'Обеспечить многопоточную безопасность для предотвращения
'параллельного выполнения операций чтения/записи
SyncLock (Me)
m_ReceiveStatus = newStatus
End SyncLock 'end lock
End Sub
'--------------------------------------------------
' (in) filename: желаемое имя для входного файла IR
'--------------------------------------------------
Public Sub New(ByVal filename As String, ByVal irdaServiceName As String)
'Имя сокета IrDA, который мы хотим открыть
m_IrDAServiceName = irdaServiceName
'Имя файла, в котором мы хотим сохранить полученные данные
m_fileNameForDownload = filename
End Sub
'----------------------------------------------------------
'Обеспечивает асинхронный прием файла через IR
' (in) filename: имя файла, в который осуществляется запись
'----------------------------------------------------------
Public Sub WaitForIRFileDownloadAsync()
'Заметьте, что сейчас мы находимся в режиме подготовки
setStatus(ReceiveStatus.NotDone_SettingUp)
'-------------------
'Создать новый поток
'-------------------
Dim threadEntryPoint As System.Threading.ThreadStart
threadEntryPoint = _
New System.Threading.ThreadStart(AddressOf WaitForIRFileDownload)
Dim newThread As System.Threading.Thread = _
New System.Threading.Thread(threadEntryPoint)
'Запустить поток на выполнение
newThread.Start()
End Sub
'------------------------------------------
'Открывает порт IR и ожидает загрузки файла
'------------------------------------------
Public Sub WaitForIRFileDownload()
Dim outputStream As System.IO.Stream
Dim irdaClient As System.Net.Sockets.IrDAClient
Dim irStreamIn As System.IO.Stream
Try
'=========================================================
'Задать и загрузить файл!
'=========================================================
internal_WaitForIRFileDownload(outputStream, irdaClient, irStreamIn)
Catch 'Поглотить любые возникающие ошибки
setStatus(ReceiveStatus.Done_ErrorOccured)
End Try
'=============================================
'Освободить все ресурсы
'=============================================
'Закрыть наш входной поток
If Not (irStreamIn Is Nothing) Then
Try
irStreamIn.Close()
Catch 'Поглотить любые возникающие ошибки
End Try
End If
'Закрытие клиента IrDA
If Not (irdaClient Is Nothing) Then
Try
irdaClient.Close()
Catch 'Поглотить любые возникающие ошибки
End Try
End If
'Закрыть файл, в который осуществлялась запись
If Not (outputStream Is Nothing) Then
Try
outputStream.Close()
Catch 'Поглотить любые возникающие ошибки
End Try
End If
'Закрыть прослушивающее устройство, если оно выполняется
If Not (m_irListener Is Nothing) Then
'Установить первым, чтобы код, выполняющийся другим потоком,
'был отменен, если он установлен
m_wasListenerStopped = True
Try
m_irListener.Stop()
Catch 'Поглотить любые возникающие ошибки
End Try
m_irListener = Nothing
End If
End Sub
Private Sub internal_WaitForIRFileDownload( _
ByRef outputStream As System.IO.Stream, _
ByRef irdaClient As System.Net.Sockets.IrDAClient, _
ByRef irStreamIn As System.IO.Stream)
'---------------------------------------------------------
'Открыть входной файл для направления в него потока данных
'---------------------------------------------------------
outputStream = System.IO.File.Open( _
m_fileNameForDownload, _
System.IO.FileMode.Create)
'==========================================
'ОБНОВЛЕНИЕ СОСТОЯНИЯ
'==========================================
setStatus(ReceiveStatus.NotDone_WaitingForSender)
'---------------------------------
'Открыть прослушивающее устройство
'---------------------------------
Try
m_wasListenerStopped = False
m_irListener = _
New System.Net.Sockets.IrDAListener(m_IrDAServiceName)
m_irListener.Start()
Catch eListener As System.Exception
m_errorDuringTransfer = "Error creating listener - " + _
eListener.Message
GoTo exit_sub_with_error
End Try
'Проверить, не поступила ли команда отменить выполнение
If (m_wasListenerStopped = True) Then
GoTo exit_sub_with_abort
End If
'------------------
'Принять соединение
'------------------
Try
'--------------------------------------------------------------------
'Выполнение будет приостановлено здесь до тех пор, пока устройство не
'начнет передавать информацию, или не будет остановлен объект
'прослушивания, выполняющийся в другом потоке)
'--------------------------------------------------------------------
irdaClient = m_irListener.AcceptIrDAClient()
Catch eClientAccept As System.Exception
'Если прослушивание остановлено другим потоком, инициировавшим отмену
'выполнения, будет сгенерировано исключение и управление будет
'передано сюда.
If (m_wasListenerStopped = True) Then
GoTo exit_sub_with_abort
End If
'Если прослушивание не было прекращено,
'то произошло иное исключение. Обработать его.
m_errorDuringTransfer = "Error accepting connection - " + _
eClientAccept.Message
GoTo exit_sub_with_error
End Try
'В этом месте возможны два состояния:
'#1: Мы получили соединение от передающего устройства IR
'#2: IR-запрос был отменен (кто-то вызвал функцию STOP)
' (в этом случае приведенный ниже код сгенерирует исключение)
'Проверить, не было ли отменено выполнение
If (m_wasListenerStopped = True) Then
GoTo exit_sub_with_abort
End If
'==========================================
'ОБНОВЛЕНИЕ СОСТОЯНИЯ
'==========================================
setStatus(ReceiveStatus.NotDone_Receiving)
'-------------------------
'Открыть принимающий поток
'-------------------------
Try
irStreamIn = irdaClient.GetStream()
Catch exGetInputStream As System.Exception
m_errorDuringTransfer = "Error getting input stream - " + _
exGetInputStream.Message
GoTo exit_sub_with_error
End Try
'Приготовиться к получению данных!
Const BUFFER_SIZE As Integer = 1024
Dim inBuffer() As Byte
ReDim inBuffer(BUFFER_SIZE)
Dim bytesRead As Integer
Do
'Считать байты из порта IR
bytesRead = irStreamIn.Read(inBuffer, 0, BUFFER_SIZE)
'Записать байты в наш выходной поток
If (bytesRead > 0) Then
outputStream.Write(inBuffer, 0, bytesRead)
End If
Loop While (bytesRead > 0)
outputStream.Flush() 'Закончить запись любых выходных данных
'==========================================
'ОБНОВЛЕНИЕ СОСТОЯНИЯ: УСПЕШНО ВЫПОЛНЕНО
'==========================================
setStatus(ReceiveStatus.Done_Success)
Return 'No errors
'==========================================
'ОШИБКА.
'==========================================
exit_sub_with_abort:
'ОБНОВЛЕНИЕ СОСТОЯНИЯ: Отменено (но не из-за ошибки)
setStatus(ReceiveStatus.Done_Aborted)
Return
exit_sub_with_error:
'ОБНОВЛЕНИЕ СОСТОЯНИЯ: ОШИБКА!!!!
setStatus(ReceiveStatus.Done_ErrorOccured)
End Sub
End Class
- Листинг 15.1. Простой код файлового ввода-вывода, иллюстрирующий различия между локальной и удаленной передачей данных
- Листинг 15.2. Имитация сбоев при передаче данных для тестирования приложения
- Листинг 15.3. Тестовый код, который необходимо поместить в класс формы для тестирования передачи и приема данных посредством механизма IrDA
- Листинг 15.4. Класс IrDAFileSend
- Листинг 15.5. Класс IrDAFileReceive
- Листинг 15.6. Простая Web-служба
- Листинг 15.7. Вызовы Web-служб с передачей параметров только явным образом
- Листинг 15.8. Вызов Web-служб путем неявной передачи параметров посредством cookie-файлов
- Листинг 15.9. Неэффективная организация диалога с Web-службой, в которой используется множество вызовов
- Листинг 15.10. Группирование запросов в одном вызове Web-службы
- Листинг 15.11. Код для загрузки файла с Web-сервера
- Листинг 15.8. Вызов Web-служб путем неявной передачи параметров посредством cookie-файлов
- Листинг 15.10. Группирование запросов в одном вызове Web-службы
- Листинг 10.1. (simpleid.c) Отображение идентификаторов пользователя и группы
- Листинг 15.11. Код для загрузки файла с Web-сервера
- Листинг 3.1. Конфигурационный файл lilo.conf
- Листинг 3.2. Файл настройки программы inittab
- Листинг 3.3. Файл
- Листинг 3.4. Информация о конфигурации и состоянии сети
- Листинг 4.1. Файл
- Листинг 4.2. Содержимое конфигурационного файла
- Листинг 4.3. Информация о программе sudo
- Листинг 5.1. Файл конфигурации sshd