So I'm building a small little program to send out/receive a UDP broadcast. I realize that UDP is not recommended but I won't know the IP address.
Here is what the client is sending out:
'Send "Hello Message" to ALL UDPListners
Public Sub UDPSendHello()
Dim client As New UDPClient()
Dim ip As New IPEndPoint(IPAddress.Broadcast, 15000)
Dim bytes As Byte() = Encoding.ASCII.GetBytes("Hello?")
client.Send(bytes, bytes.Length, ip)
client.Close()
End Sub
For the Server, I get the message "hello" and find the IP address like so:
'Reciever (Server)
Private ReadOnly udp As New UdpClient(15000)
Public Sub UDPHelloListner()
udp.BeginReceive(AddressOf Receive, New Object())
End Sub
Private Sub Receive(ByVal ar As IAsyncResult)
Dim ip As New IPEndPoint(IPAddress.Any, 15000)
Dim bytes As Byte() = udp.EndReceive(ar, ip)
Dim message As String = Encoding.ASCII.GetString(bytes)
If message = "Hello?" Then
Dim sender As New IPEndPoint(IPAddress.Any, 15000)
Dim senderRemote As EndPoint = CType(sender, EndPoint)
My.Settings.clientIPAddress = (ip.AddressFamily.ToString() + ip.Address.ToString)
MessageBox.Show(My.Settings.clientIPAddress)
' ListBox1.Items.Add(My.Settings.clientIPAddress)
End If
UDPHelloListner()
End Sub
Now I can use MessageBox.Show(My.Settings.clientIPAddress) to show the IP address of the client who is sending the message. So the above WORKS!
Now if I had 4 instances of this program broadcasting the above as a Client. How could I list each IP of those 4 instances that are running the client? I used ' ListBox1.Items.Add(My.Settings.clientIPAddress) but it says that "The calling thread cannot access this object because a different thread owns it."
If you use WPF try this:
Dispatcher.Invoke(Sub() ListBox1.Items.Add(My.Settings.clientIPAddress))
If you use WinForms:
Invoke(Sub() ListBox1.Items.Add(My.Settings.clientIPAddress))
In both cases I mean that your code is in Window class.
Related
Frequently undesirable messages are received even after any good spam/virus filter.
As a secondary wall, we suggest our user to check the suspicious message properties ('internet headers') to verify the real origin. This action, for the non-tech guys is not easy.
I wrote a simple application to drag the message into it and analyze the headers locating IP addresses and origin: obviously, if the message is from your mother, you know she is not in China...
How can we get the 'internet headers' from the message? Is there any hidden property there?
Private Sub MainForm_DragDrop(sender As Object, e As DragEventArgs) Handles Me.DragDrop
Dim myOlApp As New Outlook.Application
Dim myExp As Outlook.Explorer = myOlApp.ActiveExplorer
Dim myMailItem As Outlook.MailItem = DirectCast(myExp.Selection.Item(1), Outlook.MailItem)
Dim x = myMailItem.Body
myExp = Nothing
myMailItem = Nothing
myOlApp = Nothing
End Sub
This works fine to get the body and other data like To, From etc, however no property expose 'Internet Headers'.
You need to read the PR_TRANSPORT_MESSAGE_HEADERS MAPI property:
Dim headers As String = myMailItem.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x007D001F")
DMX 512 receiver , i need to send data in 512 lines through serial port communication .The problem arises when i need to send data at a baud rate 250000 . Then i used DCB Control block with Getcomm state and Set Comm state . and then i writefile but should i use comPort.Write (Serial comPort = new Serial Port) to send data or WriteFile .This is my below program
I have a VB.Net program of Serial Port communication program of sending data to DMX 512 receiver which i need to convert into c# . But i am confused as they have used MSCOMM1.OUTPUT to send data .
Your help highly appreciated
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Public data_array
Private Sub cmd_Start_Click()
setup_com_port
send_comm_data
End Sub
Private Sub cmd_Stop_Click()
If MSComm1.PortOpen = True Then
''MSComm1.PortOpen = False
End
End If
End Sub
Private Sub Form_Load()
data_array = Array(&H7, &H20, &H7)
Slider_Red = &H7
Slider_Green = &H20
Slider_Blue = &H7
End Sub
Private Sub setup_com_port()
MSComm1.CommPort = 2
MSComm1.Settings = "9600,N,8,2"
'MSComm1.InputLen = 0
' MSComm1.InBufferSize = 1024
' MSComm1.OutBufferSize = 1024
MSComm1.PortOpen = True
SetBaudRate MSComm1, 250000
End Sub
' Set baud rate using Win32 API.
' The PortOpen property should be set to True before calling.
' May raise the following errors:
' comPortNotOpen the PortOpen property has not been set to True
' comDCBError failed to read current state of the port
' comSetCommStateFailed failed to set new baud rate
Sub SetBaudRate(Com As MSComm, baud As Long)
Dim ComDcb As dcb
Dim ret As Long
' Check port is open
If Not Com.PortOpen Then
Err.Raise comPortNotOpen, Com.Name, _
"Operation valid only when the port is open"
Exit Sub
End If
' Get existing Comm state
ret = GetCommState(Com.CommID, ComDcb)
If ret = 0 Then
Err.Raise comDCBError, Com.Name, _
"Could not read current state of the port"
Exit Sub
End If
' Modify state with new baud rate
ComDcb.BaudRate = baud
' Set the new Comm state
ret = SetCommState(Com.CommID, ComDcb)
If ret = 0 Then
Err.Raise comSetCommStateFailed, Com.Name, _
"Could not set port to specified baud rate"
Exit Sub
End If
End Sub
Private Sub send_comm_data()
'com_break (10)
Do
com_break (5)
'DoEvents
Sleep (5)
MSComm1.Output = Chr$(0)
'DoEvents
'Sleep (1)
send_char_0
Sleep (10)
DoEvents
Loop
End Sub
Private Sub com_break(break_in_ms)
' Set the Break condition.
MSComm1.Break = True
' Set duration to 1/10 second - 100ms
'Duration! = Timer + (break_in_ms / 100) '0.1 = 100ms
' Wait for the duration to pass.
'Do Until Timer > Duration!
'' Dummy = DoEvents()
'Loop
' Clear the Break condition.
Sleep (1)
MSComm1.Break = False
End Sub
Private Sub send_char_0()
Dim strData As String
strData = ""
For i = 0 To UBound(data_array)
'' MSComm1.Output = Chr$(data_array(i))
strData = strData & Chr$(data_array(i))
Next
For i = 1 To 509
''MSComm1.Output = Chr$(50)
strData = strData & Chr$(50)
Next
MSComm1.Output = strData
7 DoEvents
End Sub
Thanks in advance
I think I got your point since I'm hacking into this for a while now. I found a nice way to send the data correctly. Keep in mind that not all the devices are capable of sending data at 250kbps, so it could be one of your issues. Find the FTDI-based ones to use.
For my approach, we need to send data in two speeds, and this happens because the reset byte must be a zero with a relatively longer time comparing to the other ones. So you will be constantly changing baud rates.
First, configure your device:
var serialPort = new SerialPort("COM0");
serialPort.DataBits = 8;
serialPort.Handshake = Handshake.None;
serialPort.Parity = Parity.None;
serialPort.StopBits = StopBits.Two;
Here I'm starting my serial port instance with all that config you've done too. Don't forget to change the COM port to fit your needs.
Now let's say you have two byte arrays, one for the "big zero" and another for the actual information:
byte[] zero = new byte[] { 0x00 };
byte[] buffer = new byte[513];
You'll ask "why 513 bytes for the buffer?", right? Simply because the first byte is a zero that tells that the actual data is going to be sent. (from 1 to 513, so there are 512 channels)
And finally the main loop: (I obviously recommend for you to do this in a separate thread)
while (true)
{
serialPort.BaudRate = 96000;
serialPort.Write(zero, 0, zero.Length);
serialPort.BaudRate = 250000;
serialPort.Write(buffer, 0, buffer.Length);
Thread.Sleep(50);
}
Now I need your help to test it. I'm not confident that it will work flawlessly for longer times without damaging the IC, but I tried it for two hours and nothing harmful happened. Could you test it longer and send me a feedback? I would appreciate it very much. Does anyone have another approach without the need of changing the baud rates?
I need to trigger a routine, when a new email is received on a smtp server.
I foun information about plug-in develpment for outlook but i figure pugins have to be installed in client.
Well, the only way that should work for me is cacthing theNEW_MAIL envet on smtp server using a Service.
Is that possible? Thanks.
I have to catch de new email when it is received.
Validate If has an attached file.
Validate file name,
if file name is correct
get the attached file and download to a file server...
I created an script in the OutlookSession and applied as rule.
There is a tutorial: Apply rule.... has an attachment and run script
Public Sub Drc(emailItem As Outlook.MailItem)
Dim objAtt As Outlook.Attachment
Dim targetFolder As String
Dim fileName As String
Dim regxpr As String
Dim fileType As String
Dim iFrom As String
iFrom = "******"
Dim isubject As String
isubject = emailItem.Subject
If emailItem.Sender = iFrom And ValidateFileName(isubject) Then
For Each objAtt In emailItem.Attachments
fileType = Split(objAtt.DisplayName, ".")(1)
targetFolder = "C:\TestCsvDirectory\ToProcess"
If ValidateFileName(objAtt.DisplayName) And LCase(fileType) = "csv" Then
objAtt.SaveAsFile (targetFolder & "\" & objAtt.DisplayName)
End If
Next
End If
I'm trying to do a repeater (as a proxy) for logging the data exchange between a SMTP client and a server. I thought it was only easy as:
Listening the client;
Listening client IP connection;
On call, connect to the server;
Send back server message;
Send the client messages to the server and return the server feedback to the client;
But, as I saw, some servers as MS exchange send multiple feedback witch are breaking the handshaking.Like:
250-SIZE 41943040
250-PIPELINING
250-DSN
250-ENHANCEDSTATUSCODES
250-STARTTLS
250-AUTH LOGIN
250-8BITMIME
250-BINARYMIME
250 CHUNKING
Here is the class
Imports System.Text
Imports System.Net
Imports System.Net.Sockets
Imports System.Threading
Public Class SmtpProxy
Private client As TcpClient
Private cltstream As NetworkStream
Private cltreader As System.IO.StreamReader
Private cltwriter As System.IO.StreamWriter
Private smtpserver As New TcpClient
Private srvstream As NetworkStream
Private srvreader As System.IO.StreamReader
Private srvwriter As System.IO.StreamWriter
Private Shared mHostSrv As String
Public Shared Property HostSrv() As String
Get
Return mHostSrv
End Get
Set(ByVal value As String)
mHostSrv = value
End Set
End Property
Private Shared mServerPort As Integer = 25
Public Shared Property ServerPort() As Integer
Get
Return mServerPort
End Get
Set(ByVal value As Integer
)
mServerPort = value
End Set
End Property
Private Shared mUserNm As String
Public Shared Property UserNm() As String
Get
Return mUserNm
End Get
Set(ByVal value As String)
mUserNm = value
End Set
End Property
Private Shared mPassword As String
Public Shared Property Password() As String
Get
Return mPassword
End Get
Set(ByVal value As String)
mPassword = value
End Set
End Property
Public Sub New(ByVal client As TcpClient)
Me.client = client
cltstream = client.GetStream()
cltreader = New System.IO.StreamReader(cltstream)
cltwriter = New System.IO.StreamWriter(cltstream)
cltwriter.NewLine = vbCr & vbLf
cltwriter.AutoFlush = True
End Sub
Public Shared Sub Start() 'ByVal args As String())
Dim listener As New TcpListener(IPAddress.Loopback, 2525)
listener.Start()
While True
Dim handler As New SmtpProxy(listener.AcceptTcpClient())
Dim thread As Thread = New System.Threading.Thread(New ThreadStart(AddressOf handler.Run))
thread.Start()
End While
End Sub
Public Sub Run()
If mHostSrv Like "*.*.*.*" Then
Dim IpS As IPAddress = Nothing
IpS = IPAddress.Parse(mHostSrv)
smtpserver.Connect(IpS, mServerPort)
Else
smtpserver.Connect(mHostSrv, mServerPort)
End If
srvstream = smtpserver.GetStream
srvreader = New System.IO.StreamReader(srvstream)
srvwriter = New System.IO.StreamWriter(srvstream)
srvwriter.NewLine = vbCrLf
srvwriter.AutoFlush = True
Dim srvline As String = srvreader.ReadLine
cltwriter.WriteLine(srvline)
Debug.Print("Server sent: {0}", srvline & vbCrLf)
Try
Dim line As String = cltreader.ReadLine
While line IsNot Nothing
Debug.Print("Read line {0}", line)
srvwriter.WriteLine(line)
Application.DoEvents()
srvline = srvreader.ReadLine()
Debug.Print("Server sent: {0}", srvline)
cltwriter.WriteLine(srvline.Replace("-", " "))
Application.DoEvents()
line = cltreader.ReadLine()
End While
Catch ex As Exception
client.Close()
smtpserver.Close()
End Try
End Sub
End Class
I tried to read multiple server lines at a time but in the meantime the client return and error if I send the whole returned server lines...
Private Function ReadSrvLines() As String
Dim strRet As String = ""
Do
If strRet Like "220*" OrElse srvreader.EndOfStream Then Exit Do
Dim strTmp As String = srvreader.ReadLine
If strTmp Is Nothing Then Exit Do
strRet &= strTmp.Replace("-", " ") & vbCrLf
cltwriter.WriteLine(strTmp.Replace("-", " "))
Debug.Print("Server sent: {0}", strTmp.Replace("-", " ") & vbCrLf)
Loop
Return strRet
End Function
Then is anyone have any solutions to propose?
Thanks all!!
Frank
You will need to perform simultaneous asynchronous reading/writing between client and server to make this work properly. SMTP responses can contain any number of lines and client or server can return a message without the need for a command (to say bye for example). Parsing the data is also unnecessary to achieve a basic log.
Edit: If it helps, if the 3 digit message number if followed by a (minus) rather than a (space) it means that there is another line to follow.
I'm trying to send a packet using httpclient
TcpClient tc = new TcpClient(ip, 4500);
string s = "A7007000601D3B00";
byte[] arr = new byte[s.Length/2];
for ( var i = 0 ; i<arr.Length ; i++ ){
arr[i] = (byte)Convert.ToInt32(s.Substring(i*2,2), 16);
}
NetworkStream stream = tc.GetStream();
stream.Write(arr, 0, arr.Length);
tc.Close();
The problem is that it sends from port 47109, however i need to send the packet using port 46324. How do i set this?
There is an overload of the TcpClient constructor that allows you to bind it to a specific local IP address and port. See the documentation on MSDN.
The reason the example at Is there a way to specify the local port to used in tcpClient? is not working is probably because the first address on the list is not actually the local machine ip address. Something like this might fix the issue and pull the proper local IP address:
string remoteIP = "x.x.x.x";
IPAddress ipAddress = Dns.GetHostEntry(Dns.GetHostName()).AddressList.Where(x => x.AddressFamily == AddressFamily.InterNetwork).First();
IPEndPoint ipLocalEndPoint = new IPEndPoint(ipAddress, 47109);
TcpClient clientSocket = new TcpClient(ipLocalEndPoint);
clientSocket.Connect(remoteIP, 4500);