[WM][VB][窮很大簡訊伺服器]
拚了,今天要來教大家一個省錢又省時的好玩應用,假如你在手機上發簡訊覺的很痛苦的人或是別人要借你的手機來發簡訊,這時怎麼辦,接著我們就要來告訴大家用手機來當伺服器,大家可以用個人電腦透過TcpClient連到手機,透過手機SmsMessage來傳送簡訊,整個架構如下:
Step1:開啟vs2008新增一個vb WindowsForm應用程式,在表單上放入三個文字方塊伺服器輸入ip、電話用來輸入發送對方的電話號碼、簡訊用來輸入發送的文字訊息,傳送鍵將文字方塊文字送到伺服器上,最後加入ListBox用來顯示伺服器回傳訊息
Step2:撰寫PC上面Form1.vb程式碼
01 Imports System.Net.Sockets
02 Imports System.Text
03
04 Public Class Form1
05 Public client As TcpClient
06 Private readBuffer(READ_BUFFER_SIZE) As Byte
07 Const READ_BUFFER_SIZE As Integer = 1024
08 Delegate Sub SetResultLabelDelegate(ByVal txt As String)
09 Private Sub UpdateStatus(ByVal statusMessage As String)
10 '顯示所有運轉資料到ListBox上因為是跨執行緒的作業所以一定要用委派的方式
11 '才有辦法來增加資料到元件上
12 If ListBox1.InvokeRequired Then
13 ListBox1.Invoke(New SetResultLabelDelegate(AddressOf UpdateStatus), statusMessage)
14 Else
15 ListBox1.Items.Insert(0, statusMessage)
16 End If
17 End Sub
18 Private Sub StreamReceiver(ByVal ar As IAsyncResult)
19 '讀取伺服器回傳資料
20 Dim BytesRead As Integer
21 If client.Connected = False Then Return
22 SyncLock client.GetStream
23 BytesRead = client.GetStream.EndRead(ar)
24 If client.Connected = False Or BytesRead = 0 Then
25 Return
26 End If
27 End SyncLock
28 '解碼資料記得要用950代碼要不然會變成亂碼
29 UpdateStatus(Encoding.GetEncoding(950).GetString(readBuffer, 0, BytesRead))
30
31 SyncLock client.GetStream
32 client.GetStream.BeginRead(readBuffer, 0, READ_BUFFER_SIZE, AddressOf StreamReceiver, Nothing)
33 End SyncLock
34 End Sub
35 Public Sub SendData(ByVal Data As String)
36 '傳送資料到伺服器
37 SyncLock client.GetStream
38 Dim writer As New IO.StreamWriter(client.GetStream)
39 writer.Write(Data)
40 writer.Flush()
41 End SyncLock
42 End Sub
43 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
44 '按下傳送鍵把文字方塊的資訊送到伺服器
45 SendData(currentIP & "@" & txtNumber.Text & "@" & txtSMS.Text)
46 End Sub
47 Dim currentIP As String
48 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
49 '取得目前ip
50 Dim ips As Net.IPHostEntry = Net.Dns.Resolve(Net.Dns.GetHostName())
51 currentIP = ips.AddressList(0).ToString
52 '連結到伺服器
53 client = New TcpClient(txtIP.Text, 8080)
54 client.GetStream.BeginRead(readBuffer, 0, READ_BUFFER_SIZE, AddressOf StreamReceiver, Nothing)
55 End Sub
56 End Class
02 Imports System.Text
03
04 Public Class Form1
05 Public client As TcpClient
06 Private readBuffer(READ_BUFFER_SIZE) As Byte
07 Const READ_BUFFER_SIZE As Integer = 1024
08 Delegate Sub SetResultLabelDelegate(ByVal txt As String)
09 Private Sub UpdateStatus(ByVal statusMessage As String)
10 '顯示所有運轉資料到ListBox上因為是跨執行緒的作業所以一定要用委派的方式
11 '才有辦法來增加資料到元件上
12 If ListBox1.InvokeRequired Then
13 ListBox1.Invoke(New SetResultLabelDelegate(AddressOf UpdateStatus), statusMessage)
14 Else
15 ListBox1.Items.Insert(0, statusMessage)
16 End If
17 End Sub
18 Private Sub StreamReceiver(ByVal ar As IAsyncResult)
19 '讀取伺服器回傳資料
20 Dim BytesRead As Integer
21 If client.Connected = False Then Return
22 SyncLock client.GetStream
23 BytesRead = client.GetStream.EndRead(ar)
24 If client.Connected = False Or BytesRead = 0 Then
25 Return
26 End If
27 End SyncLock
28 '解碼資料記得要用950代碼要不然會變成亂碼
29 UpdateStatus(Encoding.GetEncoding(950).GetString(readBuffer, 0, BytesRead))
30
31 SyncLock client.GetStream
32 client.GetStream.BeginRead(readBuffer, 0, READ_BUFFER_SIZE, AddressOf StreamReceiver, Nothing)
33 End SyncLock
34 End Sub
35 Public Sub SendData(ByVal Data As String)
36 '傳送資料到伺服器
37 SyncLock client.GetStream
38 Dim writer As New IO.StreamWriter(client.GetStream)
39 writer.Write(Data)
40 writer.Flush()
41 End SyncLock
42 End Sub
43 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
44 '按下傳送鍵把文字方塊的資訊送到伺服器
45 SendData(currentIP & "@" & txtNumber.Text & "@" & txtSMS.Text)
46 End Sub
47 Dim currentIP As String
48 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
49 '取得目前ip
50 Dim ips As Net.IPHostEntry = Net.Dns.Resolve(Net.Dns.GetHostName())
51 currentIP = ips.AddressList(0).ToString
52 '連結到伺服器
53 client = New TcpClient(txtIP.Text, 8080)
54 client.GetStream.BeginRead(readBuffer, 0, READ_BUFFER_SIZE, AddressOf StreamReceiver, Nothing)
55 End Sub
56 End Class
Step3:在此專案在加入新增一個vb 智慧型裝置專案,在表單上面產生一個ListBox用來顯示Client所傳送過來的資料以及伺服器上運作的訊息,二個功能鍵啟動、結束用來運轉伺服器
Step4:撰寫Mobile上Form1.vb程式碼用來伺服器等候每個Client連結及傳送簡訊
01 Imports System.Net.Sockets
02 Imports Microsoft.WindowsMobile.PocketOutlook
03 Imports System.Net
04
05 Public Class Form1
06 Private listener As TcpListener
07 Private listenerThread As Threading.Thread
08 Private Sub DoListen()
09 '取得目前的ip
10 Dim ThisHost As IPHostEntry = Dns.GetHostByName(Dns.GetHostName)
11 Dim currentIP As String = ThisHost.AddressList(1).ToString()
12 '開始啟動伺服器
13 listener = New TcpListener(IPAddress.Parse(currentIP), 8080)
14 listener.Start()
15 Do
16 '等待Client的連結
17 Dim c As TcpClient = listener.AcceptTcpClient
18 Dim client As New User(c)
19 AddHandler client.SMS, AddressOf Service
20 AddHandler client.Message, AddressOf UpdateStatus
21 Loop Until False
22 End Sub
23 Private Sub Service(ByVal sender As User, ByVal tel As String, ByVal msg As String)
24 '接收user要發的簡訊事件
25 If tel.Length > 0 And msg.Length > 0 Then
26 If SendSMS(tel, msg) Then
27 sender.SendData("訊息已傳送")
28 Else
29 sender.SendData("訊息未傳送")
30 End If
31 End If
32 End Sub
33 Private Function SendSMS(ByVal tel As String, ByVal message As String) As Boolean
34 '透過PocketOutlook傳送簡訊
35 Dim sms As New SmsMessage(tel, message)
36 sms.Send()
37 Return True
38 End Function
39 '按下啟動鍵
40 Private Sub MenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItem1.Click
41 '利用多執行緒來啟動伺服器接聽動作
42 UpdateStatus("啟動")
43 listenerThread = New Threading.Thread(AddressOf DoListen)
44 listenerThread.IsBackground = True
45 listenerThread.Start()
46 End Sub
47 Delegate Sub SetResultLabelDelegate(ByVal txt As String)
48 Public Sub UpdateStatus(ByVal statusMessage As String)
49 '顯示所有運轉資料到ListBox上因為是跨執行緒的作業所以一定要用委派的方式
50 '才有辦法來增加資料到元件上
51 If ListBox1.InvokeRequired Then
52 ListBox1.Invoke(New SetResultLabelDelegate(AddressOf UpdateStatus), statusMessage)
53 Else
54 ListBox1.Items.Insert(0, statusMessage)
55 ListBox1.Refresh()
56 End If
57 End Sub
58 '按下結束鍵
59 Private Sub MenuItem2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItem2.Click
60 '停止執行緒
61 listener.Stop()
62 '應用程式結束
63 Application.Exit()
64 End Sub
65 End Class
02 Imports Microsoft.WindowsMobile.PocketOutlook
03 Imports System.Net
04
05 Public Class Form1
06 Private listener As TcpListener
07 Private listenerThread As Threading.Thread
08 Private Sub DoListen()
09 '取得目前的ip
10 Dim ThisHost As IPHostEntry = Dns.GetHostByName(Dns.GetHostName)
11 Dim currentIP As String = ThisHost.AddressList(1).ToString()
12 '開始啟動伺服器
13 listener = New TcpListener(IPAddress.Parse(currentIP), 8080)
14 listener.Start()
15 Do
16 '等待Client的連結
17 Dim c As TcpClient = listener.AcceptTcpClient
18 Dim client As New User(c)
19 AddHandler client.SMS, AddressOf Service
20 AddHandler client.Message, AddressOf UpdateStatus
21 Loop Until False
22 End Sub
23 Private Sub Service(ByVal sender As User, ByVal tel As String, ByVal msg As String)
24 '接收user要發的簡訊事件
25 If tel.Length > 0 And msg.Length > 0 Then
26 If SendSMS(tel, msg) Then
27 sender.SendData("訊息已傳送")
28 Else
29 sender.SendData("訊息未傳送")
30 End If
31 End If
32 End Sub
33 Private Function SendSMS(ByVal tel As String, ByVal message As String) As Boolean
34 '透過PocketOutlook傳送簡訊
35 Dim sms As New SmsMessage(tel, message)
36 sms.Send()
37 Return True
38 End Function
39 '按下啟動鍵
40 Private Sub MenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItem1.Click
41 '利用多執行緒來啟動伺服器接聽動作
42 UpdateStatus("啟動")
43 listenerThread = New Threading.Thread(AddressOf DoListen)
44 listenerThread.IsBackground = True
45 listenerThread.Start()
46 End Sub
47 Delegate Sub SetResultLabelDelegate(ByVal txt As String)
48 Public Sub UpdateStatus(ByVal statusMessage As String)
49 '顯示所有運轉資料到ListBox上因為是跨執行緒的作業所以一定要用委派的方式
50 '才有辦法來增加資料到元件上
51 If ListBox1.InvokeRequired Then
52 ListBox1.Invoke(New SetResultLabelDelegate(AddressOf UpdateStatus), statusMessage)
53 Else
54 ListBox1.Items.Insert(0, statusMessage)
55 ListBox1.Refresh()
56 End If
57 End Sub
58 '按下結束鍵
59 Private Sub MenuItem2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItem2.Click
60 '停止執行緒
61 listener.Stop()
62 '應用程式結束
63 Application.Exit()
64 End Sub
65 End Class
Step5:撰寫User.vb用來定義每個接上來的Client
01 Imports System.Net.Sockets
02 Imports System.Text
03
04 Public Class User
05 Public client As TcpClient
06 Const READ_BUFFER_SIZE As Integer = 2048
07 Private readBuffer(READ_BUFFER_SIZE) As Byte
08 Public Sub New(ByVal client As TcpClient)
09 'client連結至伺服器產生一個Class來處理所有的事件
10 Me.client = client
11 Me.client.GetStream.BeginRead(readBuffer, 0, READ_BUFFER_SIZE, AddressOf StreamReceiver, Nothing)
12 End Sub
13 Public Sub SendData(ByVal Data As String)
14 '傳送資料至client
15 SyncLock client.GetStream
16 Dim writer As New IO.StreamWriter(client.GetStream, System.Text.Encoding.GetEncoding(950))
17 writer.Write(Data)
18 writer.Flush()
19 End SyncLock
20 End Sub
21 Public Event Message(ByVal Data As String)
22 Public Event SMS(ByVal sender As User, ByVal tel As String, ByVal msg As String)
23 Private Sub StreamReceiver(ByVal ar As IAsyncResult)
24 '接收client所傳送上來的資料
25 Dim BytesRead As Integer
26 SyncLock client.GetStream
27 BytesRead = client.GetStream.EndRead(ar)
28 End SyncLock
29 '把client的資料解碼記得中文的代碼是950要不然取得資料會變亂碼
30 Dim data As String = Encoding.GetEncoding(950).GetString(readBuffer, 0, BytesRead)
31 Dim ip As String = data.Split("@").GetValue(0)
32 Dim tel As String = data.Split("@").GetValue(1)
33 Dim msg As String = data.Split("@").GetValue(2)
34 '觸發傳送簡訊事件給外部的主程式
35 RaiseEvent SMS(Me, tel, msg)
36 '觸發訊息事件給外部的主程式
37 RaiseEvent Message("ip:" & ip & "電話:" & tel & "訊息:" & msg)
38 SyncLock client.GetStream
39 client.GetStream.BeginRead(readBuffer, 0, READ_BUFFER_SIZE, AddressOf StreamReceiver, Nothing)
40 End SyncLock
41 End Sub
42 End Class
02 Imports System.Text
03
04 Public Class User
05 Public client As TcpClient
06 Const READ_BUFFER_SIZE As Integer = 2048
07 Private readBuffer(READ_BUFFER_SIZE) As Byte
08 Public Sub New(ByVal client As TcpClient)
09 'client連結至伺服器產生一個Class來處理所有的事件
10 Me.client = client
11 Me.client.GetStream.BeginRead(readBuffer, 0, READ_BUFFER_SIZE, AddressOf StreamReceiver, Nothing)
12 End Sub
13 Public Sub SendData(ByVal Data As String)
14 '傳送資料至client
15 SyncLock client.GetStream
16 Dim writer As New IO.StreamWriter(client.GetStream, System.Text.Encoding.GetEncoding(950))
17 writer.Write(Data)
18 writer.Flush()
19 End SyncLock
20 End Sub
21 Public Event Message(ByVal Data As String)
22 Public Event SMS(ByVal sender As User, ByVal tel As String, ByVal msg As String)
23 Private Sub StreamReceiver(ByVal ar As IAsyncResult)
24 '接收client所傳送上來的資料
25 Dim BytesRead As Integer
26 SyncLock client.GetStream
27 BytesRead = client.GetStream.EndRead(ar)
28 End SyncLock
29 '把client的資料解碼記得中文的代碼是950要不然取得資料會變亂碼
30 Dim data As String = Encoding.GetEncoding(950).GetString(readBuffer, 0, BytesRead)
31 Dim ip As String = data.Split("@").GetValue(0)
32 Dim tel As String = data.Split("@").GetValue(1)
33 Dim msg As String = data.Split("@").GetValue(2)
34 '觸發傳送簡訊事件給外部的主程式
35 RaiseEvent SMS(Me, tel, msg)
36 '觸發訊息事件給外部的主程式
37 RaiseEvent Message("ip:" & ip & "電話:" & tel & "訊息:" & msg)
38 SyncLock client.GetStream
39 client.GetStream.BeginRead(readBuffer, 0, READ_BUFFER_SIZE, AddressOf StreamReceiver, Nothing)
40 End SyncLock
41 End Sub
42 End Class
Step6:來一測吧,首先執行二個pc 應用程式用來模擬多點所傳出的發送訊息,在來執行Mobile應用程式按下右下角的啟動鍵,這次我們透過Cellular Emulator來看mobile是否有送出PC所發出的簡訊,當mobile準備好了接著我可以回到pc 應用程式輸入相關資訊在按下傳送
其實這樣的應用並不難還有很多的玩法,如果大家都透過你的手機來發簡訊也可以做一個完整的記錄出帳單賺一筆小錢喔!