Writing Mobile Code Essential Software Engineering for Building Mobile Applications [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Writing Mobile Code Essential Software Engineering for Building Mobile Applications [Electronic resources] - نسخه متنی

Ivo Salmre

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید











Chapter 15 (Communications) Samples

Listing 15.1. Trivial File I/O Code That Notes Local vs. Server Differences


This is just a series of function calls. It should be easy for VB programmers to follow the C# code.

Listing 15.2. Simulating Communications Failure to Test Your Application



'Conditional compile flags for our insturmented code
#Const DEBUG_SIMULATE_FAILURES = 1 'Simulate failures
'#Const DEBUG_SIMULATE_FAILURES = 0 'Don't simulate failures
'-------------------------------------------------------------
'A global variable we want to use to indicate that we
'should throw an exception during communications
'-------------------------------------------------------------
#If DEBUG_SIMULATE_FAILURES <> 0 Then
'Variable that holds next pending failure
Shared g_failureCode As SimulatedFailures = _
SimulatedFailures.noFailurePending
'List of failures that we want to simulate
public enum SimulatedFailures
noFailurePending 'No test failures pending
'Simulated failures:
failInNextWriteSocketCode
failInNextWebServiceCall
failInNextFileIODuringFileOpen
failInNextFileIODuringFileRead
'etc.
End Enum
#End If 'DEBUG_SIMULATE_FAILURES
'-------------------------------------------------------------
'The function we import to communicate data.
'-------------------------------------------------------------
Private Sub writeDataToSocket( _
ByVal mySocket As System.Net.Sockets.Socket, _
ByVal dataToSend() As Byte)
'------------------------------------------------------------
'Only compile this code in if we are testing network failures
'------------------------------------------------------------
#If DEBUG_SIMULATE_FAILURES <> 0 Then
'If this is the failure we want to test, throw an Exception
If (g_failureCode = _
SimulatedFailures.failInNextWriteSocketCode) Then
'Reset the failure so it does not occur next time
'this function is called
g_failureCode = SimulatedFailures.noFailurePending
Throw New Exception("Test communications failure: " + _
g_failureCode.ToString())
End If
#End If
'Send the data as normal.
mySocket.Send(dataToSend)
End Sub

Listing 15.3. Test Code to Go Inside a Form Class to Test IrDA Transmit and Receive



'The name we want to give to our IrDA socket
Const myIrDASocketName As String = "IrDaTestFileTransmit"
Private Sub buttonTestFileSend_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles buttonTestFileSend.Click
'Create a simple text file we want to send
Const fileName As String = "\myTestSendFile.txt"
Dim textFileStream As System.IO.StreamWriter
textFileStream = System.IO.File.CreateText(fileName)
textFileStream.WriteLine("Today...")
textFileStream.WriteLine("is a nice day")
textFileStream.WriteLine("to go swim")
textFileStream.WriteLine("in the lake")
textFileStream.Close()
Dim irdaFileSender As IrDAFileSend
irdaFileSender = New IrDAFileSend(fileName, myIrDASocketName)
'We have 2 options: 1 - Sync, 2 - Async
'1. Call the function synchronously
'and block the thread until the
'file is sent
'1a. Let the user know we're waiting to send
Me.Text = "Trying to send..."
' '1b. Wait until we find a client and then send the file
irdaFileSender.LoopAndAttemptIRSend()
'1c. Let the user know the file has been transmitted
MsgBox("File sent!")
Me.Text = "IrDA: Sent!"
'2. Call the function async and set
'up a background thread to do the sending
'irdaFileSend.LoopAndAttemptIRSendAsync()
'NOTE: If we call the function async, we want to
'occasionally check if it is finished by
'calling 'irdaFileSend.Status'
End Sub
Private Sub buttonTestFileReceive_Click(ByVal sender As Object _
, ByVal e As EventArgs) Handles buttonTestFileReceive.Click
'If our destination file exists, delete it
Const fileName As String = "\myTestReceiveFile.txt"
If (System.IO.File.Exists(fileName)) Then
System.IO.File.Delete(fileName)
End If
Dim irdaFileReceiver As IrDAFileReceive
irdaFileReceiver = New IrDAFileReceive(fileName, _
myIrDASocketName)
'We have 2 options: 1 - Sync, 2 - Async
'1. Call the function synchronously
'and block the thread until the
'file is received
'1a. Let the user know we're waiting to receive
Me.Text = "Waiting to receive..."
'1b. Wait until someone contacts us and sends the file
irdaFileReceiver.WaitForIRFileDownload()
'1c. Let the user know we've got the sent file
Me.Text = "IrDA: received!"
MsgBox("File received!")
'2. Call the function async and set
'up a background thread to do the receive
'irdaFileReceive.WaitForIRFileDownloadAsync()
'NOTE: If we call the function async, we want to
'occasionally check if it is finished by
'calling 'irdaFileReceive.Status'
End Sub

Listing 15.4. IrDAFileSend Class



Option Strict On
'=============================================================
'This class is an IrDA client. It looks for an IrDA
'server with a matching IrDA service name and when found
'it streams the data of a file to it.
'=============================================================
Class IrDAFileSend
Private m_descriptionOfLastSendAttempt As String
Private m_IrDAServiceName As String
Private m_fileToSend As String
Private m_wasSenderStopped As Boolean
Public Enum SendStatus
AttemptingToSend
Finished_Successfully
Finished_Aborted
Finished_Error
End Enum
Private m_SendStatus As SendStatus
Public ReadOnly Property Status() As SendStatus
Get
'Lock prevents concurrent read/write to m_SendStatus
SyncLock (Me)
Return m_SendStatus
End SyncLock
End Get
End Property
Private Sub setStatus(ByVal newStatus As SendStatus)
'Lock prevents concurrent read/write to m_SendStatus
SyncLock (Me)
m_SendStatus = newStatus
End SyncLock
End Sub
Public ReadOnly Property ErrorText() As String
Get
Return m_descriptionOfLastSendAttempt
End Get
End Property
'------------------------------------------------------------
'CONSTRUCTOR
'------------------------------------------------------------
Public Sub New(ByVal fileToSend As String, _
ByVal irdaServiceName As String)
'The name of the IrDA socket we want to look for
m_IrDAServiceName = irdaServiceName
'The file we want to send
m_fileToSend = fileToSend
End Sub
'-------------------------------------------------------------
'Starts a new thread to try to send the file
'-------------------------------------------------------------
Public Sub LoopAndAttemptIRSendAsync()
'We are in send mode
setStatus(SendStatus.AttemptingToSend)
'User has not aborted us yet
m_wasSenderStopped = False
'This is the function we want the new thread to start running
Dim threadEntryPoint As System.Threading.ThreadStart
threadEntryPoint = _
New System.Threading.ThreadStart(AddressOf _
LoopAndAttemptIRSend)
'--------------------------------------------
'Create a new thread and start it running
'--------------------------------------------
Dim newThread As System.Threading.Thread = _
New System.Threading.Thread(threadEntryPoint)
newThread.Start() 'Go!
End Sub
'-------------------------------------------------------------
'Goes in loops and tries to send the file via IR
'-------------------------------------------------------------
Public Sub LoopAndAttemptIRSend()
Dim irDASender As System.Net.Sockets.IrDAClient
Dim streamOutToIrDA As System.IO.Stream
Dim streamInFromFile As System.IO.Stream
'User has not aborted us yet
m_wasSenderStopped = False
setStatus(SendStatus.AttemptingToSend)
'------------------------------------------------------------
'Continually loop and try to send the message until
'------------------------------------------------------------
While (True)
'These should all be null going in and out of the
''sendStream(...)' call unless an exception is thrown!
irDASender = Nothing
streamOutToIrDA = Nothing
streamInFromFile = Nothing
'Attempt to send the stream
Dim bSuccess As Boolean
Try
bSuccess = sendStream(m_descriptionOfLastSendAttempt, _
streamOutToIrDA, irDASender, streamInFromFile)
Catch eUnexpected As System.Exception 'Unexpected error!!!
setStatus(SendStatus.Finished_Error) 'Note the failure
m_descriptionOfLastSendAttempt = _
"Unexpected error in IR send loop. " + eUnexpected.Message
'---------------------------------------------------
'Clean up any resources we may have allocated
'---------------------------------------------------
If Not (streamOutToIrDA Is Nothing) Then
Try
streamOutToIrDA.Close()
Catch
'Swallow any error
End Try
streamOutToIrDA = Nothing
End If
If Not (streamInFromFile Is Nothing) Then
Try
streamInFromFile.Close()
Catch
'Swallow any error
End Try
streamInFromFile = Nothing
End If
If Not (irDASender Is Nothing) Then
Try
irDASender.Close()
Catch
'Swallow any error
End Try
irDASender = Nothing
End If
Return 'Exit
End Try
'See if we succeeded
If (bSuccess = True) Then
m_descriptionOfLastSendAttempt = "Success!"
setStatus(SendStatus.Finished_Successfully)
Return
End If
'See if there was a user-driven abort
If (m_wasSenderStopped = True) Then
m_descriptionOfLastSendAttempt = "User Aborted."
setStatus(SendStatus.Finished_Aborted)
Return
End If
'Otherwise ... We have not found an IrDA server with a
'matching service name yet. We will loop and keep
'looking for one.
End While
'We will never hit this point in execution
End Sub
'------------------------------------------------------------
'Attempt to send an i/o stream (e.g. a file) over IR
'(ret):
' true: We sent the file successfully
' false: The file was not sent successfully
'------------------------------------------------------------
Private Function sendStream(ByRef errorDescription As String, _
ByRef streamOutToIrDA As System.IO.Stream, _
ByRef irDASender As System.Net.Sockets.IrDAClient, _
ByRef streamInFromFile As System.IO.Stream) As Boolean
errorDescription = "
'----------------------------------------------------------
'Create a new IRDA client
'----------------------------------------------------------
Try
'--------------------------------------------------------
'This will return pretty quickly. It will peek out there
'and will return if no one is listening.
'--------------------------------------------------------
irDASender = _
New System.Net.Sockets.IrDAClient(m_IrDAServiceName)
Catch eCreateClient As System.Exception
'A number of things could have happened here
'1: No devices may be listening
'2: A device may be listening, but may not care
' (may refuse our conversation)
errorDescription = eCreateClient.Message
Return False
End Try
'At this point a number of things could happen:
'1: We have gotten a connection from an IR receiving device
'2: The IR request has been canceled (someone called STOP).
If (m_wasSenderStopped = True) Then
irDASender.Close()
irDASender = Nothing
Return False
End If
'==========================================
'SEND THE DATA!
'==========================================
'Open the file we want to send
streamInFromFile = System.IO.File.OpenRead(m_fileToSend)
'Open the IrDA socket we want to sent out to
streamOutToIrDA = irDASender.GetStream()
Const BUFFER_SIZE As Integer = 1024
Dim inBuffer() As Byte
ReDim inBuffer(BUFFER_SIZE)
Dim bytesRead As Integer
Dim iTestAll As Integer
Dim iTestWrite As Integer
'Loop...
Do
'Read the bytes in from the file
bytesRead = streamInFromFile.Read(inBuffer, 0, BUFFER_SIZE)
iTestAll = iTestAll + 1
'Write the bytes out to our output stream
If (bytesRead > 0) Then
streamOutToIrDA.Write(inBuffer, 0, bytesRead)
iTestWrite = iTestWrite + 1
End If
Loop While (bytesRead > 0)
'Clean up output stream
streamOutToIrDA.Flush() 'Finish writing any output
streamOutToIrDA.Close() 'Close the stream
streamOutToIrDA = Nothing
'Clean up local file
streamInFromFile.Close()
streamOutToIrDA = Nothing
'Clean up IrDA port
irDASender.Close()
irDASender = Nothing
'Success!!!
Return True
End Function
End class

Listing 15.5. IrDAFileReceive Class



'---------------------------------------------------------
'Allows the reception of a file over IrDA (InfraRed port)
'
'This class is NOT re-entrant and should not be called by more
'than one caller at a time. If multiple simultaneous IR
'sessions are desired, they should be done by creating
'different instances of this class.
'---------------------------------------------------------
Public Class IrDAFileReceive
Private m_wasListenerStopped As Boolean
Private m_IrDAServiceName As String
Private m_fileNameForDownload As String
Private m_errorDuringTransfer 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
'--------------------------------------------------------------
'This notes the status of the receive
'--------------------------------------------------------------
Public Enum ReceiveStatus
NotDone_SettingUp
NotDone_WaitingForSender
NotDone_Receiving
Done_Success
Done_Aborted
Done_ErrorOccured
End Enum
'---------------------------------------------------------
' Returns the state of transfer
'---------------------------------------------------------
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)
'Thread safty to aSub read and write at same time
SyncLock (Me)
m_ReceiveStatus = newStatus
End SyncLock 'end lock
End Sub
'-------------------------------------------------------------
' (in) filename: Filename we want to the IR file into
'-------------------------------------------------------------
Public Sub New(ByVal filename As String, _
ByVal irdaServiceName As String)
'The name of the IrDA socket we want to open
m_IrDAServiceName = irdaServiceName
'The filename we want to save the received data to
m_fileNameForDownload = filename
End Sub
'-----------------------------------------------------------
'Allows you to receive a file asynchronously over IR
'
' (in) filename: Filename to write to
'-----------------------------------------------------------
Public Sub WaitForIRFileDownloadAsync()
'Note that we are now in setup mode
setStatus(ReceiveStatus.NotDone_SettingUp)
'-----------------------------------------------------------
'Create a new thread
'-----------------------------------------------------------
Dim threadEntryPoint As System.Threading.ThreadStart
threadEntryPoint = _
New System.Threading.ThreadStart(AddressOf _
WaitForIRFileDownload)
Dim newThread As System.Threading.Thread = _
New System.Threading.Thread(threadEntryPoint)
'Start the thread running
newThread.Start()
End Sub
'-----------------------------------------------------------
'Opens up an IR port and waits to download a file
'-----------------------------------------------------------
Public Sub WaitForIRFileDownload()
Dim outputStream As System.IO.Stream
Dim irdaClient As System.Net.Sockets.IrDAClient
Dim irStreamIn As System.IO.Stream
Try
'=========================================================
'Set up and download the file!
'=========================================================
internal_WaitForIRFileDownload(outputStream, irdaClient, _
irStreamIn)
Catch 'Swallow any errors that occurred
setStatus(ReceiveStatus.Done_ErrorOccured)
End Try
'=============================================
'Clean up all resources
'=============================================
'Close our input stream
If Not (irStreamIn Is Nothing) Then
Try
irStreamIn.Close()
Catch 'Swallow any errors that occured
End Try
End If
'Close the IrDA client
If Not (irdaClient Is Nothing) Then
Try
irdaClient.Close()
Catch 'Swallow any errors that occured
End Try
End If
'Close the file we have been writing to
If Not (outputStream Is Nothing) Then
Try
outputStream.Close()
Catch 'Swallow any errors that occured
End Try
End If
'Close the listener if its running
If Not (m_irListener Is Nothing) Then
'Set first so code running on another thread will
'abort if it is set
m_wasListenerStopped = True
Try
m_irListener.Stop()
Catch 'Swallow any errors
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)
'----------------------------------------------------------
'Open an input file to stream into
'----------------------------------------------------------
outputStream = System.IO.File.Open( _
m_fileNameForDownload, _
System.IO.FileMode.Create)
'==========================================
'STATUS UPDATE
'==========================================
setStatus(ReceiveStatus.NotDone_WaitingForSender)
'-------------------------------------------------------------
'Open a listener
'-------------------------------------------------------------
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
'See if we got aborted
If (m_wasListenerStopped = True) Then
GoTo exit_sub_with_abort
End If
'---------------------------------------------------------
'Accept a connection
'---------------------------------------------------------
Try
'---------------------------------------------------------
'Execution will stop here until we get pinged by a device
'or the listener was halted on another thread
'---------------------------------------------------------
irdaClient = m_irListener.AcceptIrDAClient()
Catch eClientAccept As System.Exception
'If the listenting is stopped by another thread calling cancel
' an exception will be thrown and we will be here.
If (m_wasListenerStopped = True) Then
GoTo exit_sub_with_abort
End If
'If it was not a matter of the listening service being
'stopped, some other exception has occurred. Deal with it.
m_errorDuringTransfer = "Error accepting connection - " + _
eClientAccept.Message
GoTo exit_sub_with_error
End Try
'At this point we will be in 1 of 2 states, either:
'1: We have gotten a connection from an IR sending device
'2: The IR request has been canceled (by someone calling STOP)
' (in which the code below will throw an exception)
'See if we got aborted
If (m_wasListenerStopped = True) Then
GoTo exit_sub_with_abort
End If
'==========================================
'STATUS UPDATE
'==========================================
setStatus(ReceiveStatus.NotDone_Receiving)
'--------------------------------------------------------------
'Open a receiving stream
'--------------------------------------------------------------
Try
irStreamIn = irdaClient.GetStream()
Catch exGetInputStream As System.Exception
m_errorDuringTransfer = "Error getting input stream - " + _
exGetInputStream.Message
GoTo exit_sub_with_error
End Try
'Get ready to receive the data!
Const BUFFER_SIZE As Integer = 1024
Dim inBuffer() As Byte
ReDim inBuffer(BUFFER_SIZE)
Dim bytesRead As Integer
Do
'Read the bytes in from the IR port
bytesRead = irStreamIn.Read(inBuffer, 0, BUFFER_SIZE)
'Write the bytes out to our output stream
If (bytesRead > 0) Then
outputStream.Write(inBuffer, 0, bytesRead)
End If
Loop While (bytesRead > 0)
outputStream.Flush() 'Finish writing any output
'==========================================
'STATUS UPDATE: SUCCESS
'==========================================
setStatus(ReceiveStatus.Done_Success)
Return 'No errors
'==========================================
'FAILURE.
'==========================================
exit_sub_with_abort:
'STATUS UPDATE: Aborted (but no error)
setStatus(ReceiveStatus.Done_Aborted)
Return
exit_sub_with_error:
'STATUS UPDATE: ERROR!!!!
setStatus(ReceiveStatus.Done_ErrorOccured)
End Sub
End Class

Listing 15.6. Simple Web Wervice



'This code snippet goes inside the Service1 class
'in the file "Service1.asmx.vb".
'
'"<WebMethod>" is meta data that tells the Web service
'engine that this method should be exposed as a Web service
<WebMethod()> _
Public Function AddTwoNumbers(ByVal x As Integer, _
ByVal y As Integer) As Integer
Return x + y
End Function

Listing 15.7. Web Service Calls with Only Explicit Parameters Being Passed


This is just a series of function calls. It should be easy for VB programmers to follow the C# code.

Listing 15.8. Web Service Calls with Implicit Parameters Passed via Cookies


This is just a series of function calls. It should be easy for VB programmers to follow the C# code.

Listing 15.9. A Chatty Conversation with a Multiple Web Service Calls


This is just a series of function calls. It should be easy for VB programmers to follow the C# code.

Listing 15.10. A Batched Conversation with a Single Web Service Call


This is just a series of function calls. It should be easy for VB programmers to follow the C# code.

Listing 15.11. Code to Download a File from a Web Server



'-------------------------------------------------------------
'Performs a synchronous download of a file on a Web server
'of a file and stores it to a local file system
' (in) httpWhereFrom: URL to file
' (e.g. "http:'someserver/somefile.jpg")
' (in) filenameWhereTo: File location to write the file to
' (e.g. "\localfile.jpg")
'-------------------------------------------------------------
Public Sub downloadFileToLocalStore(ByVal httpWhereFrom As _
String, ByVal filenameWhereTo As String)
Dim myFileStream As System.IO.FileStream = Nothing
Dim myHTTPResponseStream As System.IO.Stream = Nothing
Dim myWebRequest As System.Net.WebRequest = Nothing
Dim myWebResponse As System.Net.WebResponse = Nothing
'If the location we want to write to exists, delete it
If (System.IO.File.Exists(filenameWhereTo) = True) Then
System.IO.File.Delete(filenameWhereTo)
End If
Try
'Create a Web request
myWebRequest = _
System.Net.HttpWebRequest.Create(httpWhereFrom)
'Get the response
myWebResponse = myWebRequest.GetResponse()
'Get the stream for the response
myHTTPResponseStream = myWebResponse.GetResponseStream()
'Create a local file to stream the response to
myFileStream = System.IO.File.OpenWrite(filenameWhereTo)
'This buffer size can be tuned
Const buffer_length As Integer = 4000
Dim byteBuffer() As Byte
ReDim byteBuffer(buffer_length)
Dim bytesIn As Integer
'Read in the file and stream it to a local file
Do
'Read data in
bytesIn = myHTTPResponseStream.Read(byteBuffer, _
0, buffer_length)
'Write data out
If (bytesIn <> 0) Then
myFileStream.Write(byteBuffer, 0, bytesIn)
End If
Loop While (bytesIn <> 0)
Catch myException As Exception 'Download failed!
'Something bad happened. Let's clean up
attemptCleanup_ThrowNoExceptions(myFileStream, _
myHTTPResponseStream, myWebResponse)
'Now that we've cleaned up, rethrow the exception
'so that the application knows something went wrong!
Throw myException
End Try
'Download has succeeded!
'Let's close everyting down.
Try
'Normal clean up.
myFileStream.Close()
myFileStream = Nothing
myHTTPResponseStream.Close()
myHTTPResponseStream = Nothing
myWebResponse.Close()
myWebResponse = Nothing
Catch myException As Exception 'Failure during a close!
'Something bad happened. Let's clean up
attemptCleanup_ThrowNoExceptions(myFileStream, _
myHTTPResponseStream, myWebResponse)
'Now that we've cleaned up, rethrow the exception
'so that the the application knows something went wrong!
Throw myException
End Try
'Success!
End Sub
'------------------------------------------
'Tries to close and clean up everything
'Traps any exceptions that might be thrown.
'------------------------------------------
Sub attemptCleanup_ThrowNoExceptions( _
ByVal myFileStream As System.IO.FileStream, _
ByVal myHTTPResponseStream As System.IO.Stream, _
ByVal myWebResponse As System.Net.WebResponse)
If Not (myFileStream Is Nothing) Then
Try
myFileStream.Close()
Catch 'Do nothing.
End Try
End If
If Not (myHTTPResponseStream Is Nothing) Then
Try
myHTTPResponseStream.Close()
Catch 'Do nothing.
End Try
End If
If Not (myWebResponse Is Nothing) Then
Try
myWebResponse.Close()
Catch 'Do nothing.
End Try
End If
End Sub


/ 159