聊天应用问题 [英] Chat Application problem
问题描述
我正在尝试开发一个供办公室使用的小型聊天应用程序。我试着在网上做一些研究,想出了一些属于我自己的东西。起初它只是一个窗口,您可以在其中输入您的姓名和通讯员的IP。工作得很好!然后我决定添加高级功能,包括网络上所有人的列表,允许多个聊天,获取连接人员的照片等....
这就是它开始疯狂的地方。该应用程序正常;我的意思是我可以发送和接收消息很好,但它给了我和任何人使用app吨的错误消息,它有点滞后
我的主要表格
Hi,
I am trying to develop a small chat application for office use. I tried to do some research on the web and came up with something of my own. At first it was a single window where you would put your name and the IP of your correspondent. Worked great! Then I decided to add advanced functionalities by including a list of all the people on the network, allowing multiple chats, getting photos of the people connected, etc....
That is where it started going crazy. The app works ok; I mean I can send and receive messages fine but it gives both me and anyone using the app tons of error messages and it kind of lags a lot
My main form
Public Class MainForm
Dim listerner As New TcpListener(44444)
Dim client As TcpClient
Dim message As String = ""
Dim tts As Object
Public connString As String
Public arrImage() As Byte
Public displayName As String
Public myIP As String
Public myID As String
Public myStatus As String
Dim chat As Chat_Window
Dim Sound As New System.Media.SoundPlayer()
Private Sub MainForm_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim myMS As New IO.MemoryStream
lblUsername.Text = displayName
For Each ar As Byte In arrImage
myMS.WriteByte(ar)
Next
Dim inImg As Image = Image.FromStream(myMS)
pbProfilePic.Image = inImg
getStaffs()
listerner.Start()
Timer1.Enabled = True
Timer1.Start()
End Sub
Private Sub MainForm_FormClosing(sender As System.Object, e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
listerner.Stop()
setStatus("Offline", myID, "", "")
Using writer As New StreamWriter("closeApp.bat", False)
writer.WriteLine("Taskkill /IM ""DIOC.exe"" /F")
End Using
Process.Start("closeApp.bat")
End Sub
Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
Dim conn As OleDbConnection
Dim command As String
Dim reader As OleDbCommand
Dim sdrReader As OleDbDataReader
Dim intcount As Integer
Dim myIMGCell As New DataGridViewImageCell
Dim temp() As String
Dim friendName As String
Dim myForms As FormCollection = Application.OpenForms
Dim found As Boolean
conn = New OleDbConnection(connString)
Try
conn.Open()
command = "SELECT ID, Status, LastLoginIP FROM Staff"
reader = New OleDbCommand(command, conn)
reader.CommandType = CommandType.Text
reader.CommandText = command
sdrReader = reader.ExecuteReader
While sdrReader.Read
Dim id, ip, status As String
id = sdrReader.Item("ID").ToString
ip = sdrReader.Item("LastLoginIP").ToString
status = sdrReader.Item("Status").ToString
For intcount = 0 To dgContacts.Rows.Count - 1
If dgContacts.Rows(intcount).Cells(0).Value = id Then
dgContacts.Rows(intcount).Cells(4).Value = status
dgContacts.Rows(intcount).Cells(6).Value = ip
If status = "Offline" Then
dgContacts.Rows(intcount).Cells(3).Value = (CType(My.Resources.ResourceManager.GetObject("offline"), Image))
ElseIf status = "Online" Then
dgContacts.Rows(intcount).Cells(3).Value = (CType(My.Resources.ResourceManager.GetObject("online"), Image))
ElseIf status = "Busy" Then
dgContacts.Rows(intcount).Cells(3).Value = (CType(My.Resources.ResourceManager.GetObject("busy"), Image))
ElseIf status = "Away" Then
dgContacts.Rows(intcount).Cells(3).Value = (CType(My.Resources.ResourceManager.GetObject("away"), Image))
End If
End If
Next intcount
End While
sdrReader.Close()
conn.Close()
Catch ex As Exception
MsgBox(ex.ToString)
End Try
Try
If listerner.Pending = True Then
message = ""
client = listerner.AcceptTcpClient
Dim reader2 As New StreamReader(client.GetStream())
While reader2.Peek <> -1
message = message + Convert.ToChar(reader2.Read()).ToString
End While
Me.Focus()
temp = message.Split(" says:")
friendName = getNameFromIP(temp(0))
message = message.Replace(temp(0), friendName)
For Each frmName As Form In myForms
If frmName.Text.ToString = friendName Then
found = True
Exit For
Else
found = False
End If
Next
If found = True Then
For Each frmName As Form In myForms
If frmName.Text.ToString = friendName Then
chat.txtRead.Text = (chat.txtRead.Text + message + vbCrLf)
chat.txtRead.SelectionStart = chat.txtRead.TextLength
chat.txtRead.ScrollToCaret()
My.Computer.Audio.Play(My.Resources.alert, AudioPlayMode.Background)
frmName.Focus()
Exit For
End If
Next
Else
chat = New Chat_Window
chat.pbFriend.Image = myIMGCell.Value
chat.Text = friendName
chat.pbMe.Image = pbProfilePic.Image
chat.connString = connString
chat.myID = myID
chat.myIP = myIP
chat.friendIP = temp(0)
chat.txtRead.Text = (chat.txtRead.Text + message + vbCrLf)
chat.txtRead.SelectionStart = chat.txtRead.TextLength
chat.txtRead.ScrollToCaret()
My.Computer.Audio.Play(My.Resources.alert, AudioPlayMode.Background)
chat.Show()
End If
End If
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Private Sub getStaffs()
Dim conn As OleDbConnection
Dim command As String
Dim reader As OleDbCommand
Dim sdrReader As OleDbDataReader
Dim inImg As Image
conn = New OleDbConnection(connString)
Try
conn.Open()
command = "SELECT * FROM Staff"
reader = New OleDbCommand(command, conn)
reader.CommandType = CommandType.Text
reader.CommandText = command
sdrReader = reader.ExecuteReader
If sdrReader.HasRows Then
While sdrReader.Read()
Dim id As String = sdrReader.Item("ID").ToString
Dim picture = sdrReader.Item("Picture")
Dim name As String = sdrReader.Item("Name").ToString
Dim surname As String = sdrReader.Item("Surname").ToString
Dim status As String = sdrReader.Item("Status").ToString
Dim email As String = sdrReader.Item("Email").ToString
Dim ip As String = sdrReader.Item("LastLoginIP").ToString
If (id = myID) Then Continue While
Dim myMS As New IO.MemoryStream
arrImage = picture
For Each ar As Byte In arrImage
myMS.WriteByte(ar)
Next
If status = "Offline" Then
inImg = (CType(My.Resources.ResourceManager.GetObject("offline"), Image))
ElseIf status = "Online" Then
inImg = (CType(My.Resources.ResourceManager.GetObject("online"), Image))
ElseIf status = "Busy" Then
inImg = (CType(My.Resources.ResourceManager.GetObject("busy"), Image))
ElseIf status = "Away" Then
inImg = (CType(My.Resources.ResourceManager.GetObject("away"), Image))
End If
Dim inImg2 As Image = Image.FromStream(myMS)
dgContacts.Rows.Add(id, inImg2, name & " " & surname, inImg, status, email, ip)
End While
Else
MsgBox("Database empty!")
End If
Catch ex As Exception
MsgBox(ex.ToString)
MsgBox("Error Connecting to database")
Finally
conn.Close()
End Try
End Sub
Public Sub setStatus(ByVal status As String, ByVal id As String, ByVal ip As String, ByVal cnStrng As String)
Dim cn As New OleDb.OleDbConnection
Dim myCmd As New OleDb.OleDbCommand
If connString = "" Then
cn.ConnectionString = cnStrng
Else
cn.ConnectionString = connString
End If
cn.Open()
myCmd.Connection = cn
myCmd.CommandText = "UPDATE Staff SET Status = '" & status & "', LastLoginIP = '" & ip & "' WHERE ID = " & id & ";"
myCmd.ExecuteNonQuery()
myStatus = status
cn.Close()
End Sub
Private Sub dgContacts_CellContentClick(sender As System.Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgContacts.CellContentClick
Dim myForms As FormCollection = Application.OpenForms
Dim found As Boolean
For Each frmName As Form In myForms
If frmName.Text.ToString = dgContacts.Rows(e.RowIndex).Cells(2).Value Then
found = True
Exit For
Else
found = False
End If
Next
If found = True Then
For Each frmName As Form In myForms
If frmName.Text.ToString = dgContacts.Rows(e.RowIndex).Cells(2).Value Then
frmName.Focus()
Exit For
End If
Next
Else
chat = New Chat_Window
Dim myIMGCell As New DataGridViewImageCell
myIMGCell = dgContacts.Item("Picture", e.RowIndex)
chat.Text = dgContacts.Rows(e.RowIndex).Cells(2).Value
chat.pbMe.Image = pbProfilePic.Image
chat.pbFriend.Image = myIMGCell.Value
chat.friendIP = dgContacts.Rows(e.RowIndex).Cells(6).Value
chat.friendID = dgContacts.Rows(e.RowIndex).Cells(0).Value
chat.connString = connString
chat.myID = myID
chat.myIP = myIP
chat.myName = lblUsername.Text
chat.Show()
End If
End Sub
Private Function getNameFromIP(ByVal ip As String) As String
Dim reply As String = ""
Dim conn As OleDbConnection
Dim command As String
Dim reader As OleDbCommand
Dim sdrReader As OleDbDataReader
conn = New OleDbConnection(connString)
Try
conn.Open()
command = "SELECT (Name + ' ' + Surname) AS FullName, ID FROM Staff WHERE LastLoginIP = '" & ip & "';"
reader = New OleDbCommand(command, conn)
reader.CommandType = CommandType.Text
reader.CommandText = command
sdrReader = reader.ExecuteReader
If sdrReader.HasRows Then
sdrReader.Read()
reply = sdrReader.Item("FullName").ToString
chat.friendID = sdrReader.Item("ID").ToString
Else
End If
Catch ex As Exception
MsgBox(ex.ToString)
'MsgBox("Error Connecting to database")
Finally
conn.Close()
End Try
Return reply
End Function
End Class
我的聊天窗口
My chat window
Public Class Chat_Window
Public friendIP As String
Public friendID As String
Public myID As String
Public myIP As String
Public myName As String
Public connString As String
Dim listerner As New TcpListener(44444)
Dim client As TcpClient
Private Sub Chat_Window_Load(sender As Object, e As System.EventArgs) Handles Me.Load
Timer1.Enabled = True
Timer1.Start()
listerner.Start()
End Sub
Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
'Select Case getStatus(friendID)
'Case "Online"
'friendStatusPanel.BackColor = Color.GreenYellow
'Case "Busy"
'friendStatusPanel.BackColor = Color.Red
'Case "Away"
'friendStatusPanel.BackColor = Color.Orange
'Case "Offline"
'friendStatusPanel.BackColor = Color.White
'End Select
Select Case getStatus(myID)
Case "Online"
myStatusPanel.BackColor = Color.GreenYellow
Case "Busy"
myStatusPanel.BackColor = Color.Red
Case "Away"
myStatusPanel.BackColor = Color.Orange
Case "Offline"
myStatusPanel.BackColor = Color.White
End Select
End Sub
Private Function getStatus(ByVal id As String) As String
Dim conn As OleDbConnection
Dim command As String
Dim reader As OleDbCommand
Dim sdrReader As OleDbDataReader
Dim response As String = ""
conn = New OleDbConnection(connString)
Try
conn.Open()
command = "SELECT Status FROM Staff WHERE ID=" & id & ";"
reader = New OleDbCommand(command, conn)
reader.CommandType = CommandType.Text
reader.CommandText = command
sdrReader = reader.ExecuteReader
sdrReader.Read()
response = sdrReader.Item("Status").ToString
sdrReader.Close()
conn.Close()
Catch ex As Exception
MsgBox(ex.ToString)
End Try
Return response
End Function
Private Sub btnSend_Click(sender As System.Object, e As System.EventArgs) Handles btnSend.Click
If txtWrite.Text = "" Or txtWrite.Text = Nothing Then Exit Sub
Try
client = New TcpClient(friendIP, 44444)
Dim writer As New StreamWriter(client.GetStream())
txttempmsg.Text = (txtWrite.Text)
writer.Write(myIP + " says: " + txtWrite.Text)
txtRead.Text = (txtRead.Text + myName + " says: " + txttempmsg.Text + vbCrLf)
writer.Flush()
txtWrite.Text = ""
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
End Class
你能帮忙吗?
Can you guys help?
推荐答案
Sergy是对的 - 你需要向我们提供一些错误消息,或者我们无法帮助他们。
至于滞后 - 只是看着你的代码的一小部分,我明白为什么。你正在做这样的事情:
Sergy's right - you need to give us some of those error messages, or we just won't be able to help with them.
As for the "laggyness" - just looking at a small portion of your code, I can see why. You're doing stuff like this:
For Each ar As Byte In arrImage
myMS.WriteByte(ar)
Next
Dim inImg As Image = Image.FromStream(myMS)
pbProfilePic.Image = inImg
你需要花一些时间做一些重新分解 - 意味着通过你的代码并找到让它更具可读性的方法,更优雅,也可能更快。例如,上面的代码可以重构为:
You need to spend some time doing some re-factoring - meaning going through your code and finding ways to make it more readable, more elegant, and possibly FASTER. For instance, the code above can be refactored into:
myMS.Write(arrImage, o, arrImage.Length)
pbProfilePic.Image = Image.FromStream(myMS)
这不仅更具可读性,而且将该数组写入内存流将是更快,并且将图像添加到pbProfilePic将减少浪费的内存,因为您不需要为垃圾收集器创建额外的图像对象以立即为您释放(谁说它会?有时垃圾收集器保留在内存中由于它自己的原因很长一段时间)。
除非你给我们一些错误信息,否则我认为这是我们中最好的能够为你做。
- Pete
Not only is this more readable, but writing that array into the memorystream will be faster, and adding the image to pbProfilePic will be less wastfull of memory because you didn't need to create an extra image object for the garbage collector to immediately release for you (and who says it will? Sometimes the garbage collector holds on to memory for long periods of time for reasons of it's own).
Unless you give us some of those error messages, I think this is the best any of us is going to be able to do for you.
- Pete
对不起......我还是有点新鲜编程和学习
至于错误,每次都会出现4个错误:
以下链接是图片
错误1
Sorry about that.....I am still a bit new to programming and still learning
As for the errors there are generally 4 errors that occur every time:
Below links are images
Error 1
See the end of this message for details on invoking
just-in-time (JIT) debugging instead of this dialog box.
************** Exception Text **************
System.Net.Sockets.SocketException (0x80004005): Only one usage of each socket address (protocol/network address/port) is normally permitted
at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
at System.Net.Sockets.Socket.Bind(EndPoint localEP)
at System.Net.Sockets.TcpListener.Start(Int32 backlog)
at System.Net.Sockets.TcpListener.Start()
at DIOC.Chat_Window.Chat_Window_Load(Object sender, EventArgs e) in C:\Users\Dhanish\OneDrive\DIOC\DIOC\Chat Window.vb:line 19
at System.Windows.Forms.Form.OnLoad(EventArgs e)
at System.Windows.Forms.Form.OnCreateControl()
at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
at System.Windows.Forms.Control.CreateControl()
at System.Windows.Forms.Control.WmShowWindow(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ContainerControl.WndProc(Message& m)
at System.Windows.Forms.Form.WmShowWindow(Message& m)
at System.Windows.Forms.Form.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
************** Loaded Assemblies **************
mscorlib
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
CodeBase: file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/mscorlib.dll
----------------------------------------
DIOC
Assembly Version: 1.0.0.0
Win32 Version: 2.0.0.0
CodeBase: file:///C:/Users/Dhanish/OneDrive/DIOC/DIOC/bin/Debug/DIOC.exe
----------------------------------------
Microsoft.VisualBasic
Assembly Version: 10.0.0.0
Win32 Version: 11.0.50709.17929 built by: FX45RTMREL
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/Microsoft.VisualBasic/v4.0_10.0.0.0__b03f5f7f11d50a3a/Microsoft.VisualBasic.dll
----------------------------------------
System
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll
----------------------------------------
System.Core
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Core/v4.0_4.0.0.0__b77a5c561934e089/System.Core.dll
----------------------------------------
System.Windows.Forms
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
----------------------------------------
System.Drawing
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
----------------------------------------
System.Configuration
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Configuration/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll
----------------------------------------
System.Xml
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Xml/v4.0_4.0.0.0__b77a5c561934e089/System.Xml.dll
----------------------------------------
System.Runtime.Remoting
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Runtime.Remoting/v4.0_4.0.0.0__b77a5c561934e089/System.Runtime.Remoting.dll
----------------------------------------
System.Data
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_32/System.Data/v4.0_4.0.0.0__b77a5c561934e089/System.Data.dll
----------------------------------------
System.Transactions
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_32/System.Transactions/v4.0_4.0.0.0__b77a5c561934e089/System.Transactions.dll
----------------------------------------
System.EnterpriseServices
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_32/System.EnterpriseServices/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.EnterpriseServices.dll
----------------------------------------
************** JIT Debugging **************
To enable just-in-time (JIT) debugging, the .config file for this
application or computer (machine.config) must have the
jitDebugging value set in the system.windows.forms section.
The application must also be compiled with debugging
enabled.
For example:
<configuration>
<system.windows.forms jitdebugging="true" />
</configuration>
When JIT debugging is enabled, any unhandled exception
will be sent to the JIT debugger registered on the computer
rather than be handled by this dialog box.
这篇关于聊天应用问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!