基于Socket的简易聊天室(vb.net代码详细讲解,源代码下载)

本教程配套的视频:Socket网络通信教程,简易聊天室_哔哩哔哩_bilibili

在网上有很多这样的资料,不过基本都解释不清楚,而且有的需要付费和关注

本教程主要的目的是:使用vb.net详细讲解Socket网络编程的基本要素,如果需要C#源代码,可以使用这个网站进行翻译Code Converter C# to VB and VB to C# – Telerik

那么,就开始吧

一、建立新的解决方案,加入2个项目,分别重命名为Server和Client,可以依据自己的需求

二、设计窗体:

好,到这一步就要开始编写代码了

三、编写代码

服务端一共需要2Socket,它们分别是SockeListenSocketSend

首先是监听部分。监听服务器的哪一个端口,获取服务器的ip地址,建立新的Socket,这一个Socket负责监听

等待客户端连接服务端,就是SocketListen

由于SocketListen会在等待客户端时占用主线程,因此使用多线程,无限次地等待客户端添加

注意,客户端和服务端需要取消跨线程检查 

线程之间需要取消跨线程检查,在窗体构造函数或窗体加载事件中加入

Private Sub Server_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    CheckForIllegalCrossThreadCalls = False
End Sub

 其次SocketSend,负责收、发数据,最主要的通信Socket

引入命名空间

Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports System.Threading

 初始化

Sockets负责存储客户端Socket

Socket Listen负责等待连接客户端Socket

SocketSend负责收发数据

Dim socketListen As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
Dim SocketSend As Socket
Dim Sockets As New Dictionary(Of String, Socket)
Dim threadListen As New Thread(AddressOf Accept)

点击监听时触发事件(服务端的IP地址要更改!)

Private Sub ButListen_Click(sender As Object, e As EventArgs) Handles ButListen.Click

    Dim ip As IPAddress = IPAddress.Parse(TextIP.Text)
    Dim ipPort As IPEndPoint = New IPEndPoint(ip, TextPort.Text)
    socketListen.Bind(ipPort)
    socketListen.Listen(50)
    ShowMsg("服务端监听成功")

    threadListen.IsBackground = True
    threadListen.Start()

End Sub
Sub Accept()
    While True
        SocketSend = socketListen.Accept

        Dim ip As String = SocketSend.RemoteEndPoint.ToString
        Sockets.Add(ip, SocketSend)
        ListClient.Items.Add(ip)

        ShowMsg(ip & "连接成功,已经添加至客户端列表")

        Dim threadReceive As New Thread(AddressOf Receive)
        threadReceive.IsBackground = True
        threadReceive.Start(SocketSend)

    End While
End Sub
Function ShowMsg(s As String)
    Try
        ListLog.AppendText(s)
        ListLog.AppendText(vbCrLf)
        ListLog.SelectionStart = ListLog.Text.Length
        ListLog.ScrollToCaret()
    Catch ex As Exception
    End Try
End Function

服务端Receive(While里面的退出提示是针对Telnet客户端退出的,而错误处理部分是针对.net Socket的)

Sub Receive(SocketSend)
    Dim S As Socket = SocketSend
    Dim ip As String = S.RemoteEndPoint.ToString
    Try
        While True
            Dim buffer(1024 * 1024 * 2) As Byte
            Dim length As Integer = S.Receive(buffer)
            If length = 0 Then
                ShowMsg("服务端检测:" & ip & ":退出了客户端...")
                Sockets.Remove(ip)
                ListClient.Items.Clear()
                For Each ips In Sockets
                    ListClient.Items.Add(ips.Key)
                Next
                Exit While
            End If

            Dim str As String = Encoding.UTF8.GetString(buffer)
            ShowMsg(S.RemoteEndPoint.ToString & " 发送消息:" & str)

            Dim str1 = "[客户端]" & ip & ":" & str
            Dim buffer1(1024 * 1024 * 2) As Byte
            buffer1 = Encoding.UTF8.GetBytes(str1)
            For Each i In Sockets
                If i.Key <> ip Then
                    i.Value.Send(buffer1)
                End If
            Next
        End While


    Catch ex As Exception
        ShowMsg("服务端检测:" & ip & ":客户端出现异常,具体异常:" & ex.Message)
    If MsgBox("是否关闭此连接?" & ex.Message, vbYesNo, "Server Message") = MsgBoxResult.Yes Then
        Sockets.Remove(ip)
        ListClient.Items.Clear()
        For Each ips In Sockets
            ListClient.Items.Add(ips.Key)
        Next
    End If

    End Try

End Sub

服务端单独发送消息和全体发送消息

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim buffer(1024 * 1024 * 2) As Byte
    If TextBox3.Text.Trim.Count = 0 Then
        MsgBox("输入发送的文本")
    Else
        buffer = Encoding.UTF8.GetBytes("服务端给你发送:" & TextBox3.Text)
        Sockets(ListClient.SelectedItem).Send(buffer)
        ShowMsg("服务端给" & ListClient.SelectedItem & "发送了:" & TextBox3.Text)
    End If
End Sub

Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
    Dim buffer(1024 * 1024 * 2) As Byte
    If TextBox3.Text.Trim.Count = 0 Then
        MsgBox("输入发送的文本")
    Else
        buffer = Encoding.UTF8.GetBytes("服务端全体通知:" & TextBox3.Text)
        For Each i In Sockets
            i.Value.Send(buffer)
        Next
        ShowMsg("服务端给所有客户端发送了:" & TextBox3.Text)
    End If

End Sub

单个客户端的消息也要被其他客户端接收请看Receive方法中有“【客户端】”的一部分,服务端负责转发来自客户端的消息,除当前客户端外,这样就巧妙地实现了转发功能

这个和全体通知比较类似

客户端:客户端部分只需要负责收发数据,一切内容交给服务端处理,目前转发功能就靠服务端而不是客户端

 Client也要加上

Function ShowMsg(s As String)
    Try
        ListLog.AppendText(s)
        ListLog.AppendText(vbCrLf)
        ListLog.SelectionStart = ListLog.Text.Length
        ListLog.ScrollToCaret()
    Catch ex As Exception
    End Try
End Function

Private Sub Client_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    CheckForIllegalCrossThreadCalls = False
End Sub

初始化

Dim SocketSend As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
Dim ip As IPAddress
Dim ipPort As IPEndPoint

连接服务端:直接开启线程来接收数据

Private Sub ButConnect_Click(sender As Object, e As EventArgs) Handles ButConnect.Click
    ip = IPAddress.Parse(TextIP.Text)
    ipPort = New IPEndPoint(ip, TextPort.Text)
    SocketSend.Connect(ipPort)
    ShowMsg("成功连接到服务端")
    Dim th As New Thread(AddressOf Receive)
    th.IsBackground = True
    th.Start(SocketSend)
End Sub

Receive部分就简单了:

Sub Receive(SocketSend)
    Dim S As Socket = SocketSend
    Dim ip As String = S.RemoteEndPoint.ToString
    Try
        While True
            Dim buffer(1024 * 1024 * 2) As Byte
            Dim length As Integer = S.Receive(buffer)
            Dim str As String = Encoding.UTF8.GetString(buffer)
            ShowMsg(str)
        End While
    Catch ex As Exception
    End Try
End Sub

发送消息:

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim buffer(1024 * 1024 * 2) As Byte
    If TextBox3.Text.Trim.Count = 0 Then
        MsgBox("输入发送的文本")
    Else
        buffer = Encoding.UTF8.GetBytes(TextBox3.Text)

        SocketSend.Send(buffer)
        ShowMsg("我:" & TextBox3.Text)
    End If

End Sub

 这样,一个简易多人聊天室就完成了

源代码下载:链接:https://pan.baidu.com/s/1uvYPrGVuV3KeeLDtC4n7Zg?pwd=2333 
提取码:2333

链接永久有效

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是基于socket网络聊天室的完整代码,包括服务器端和客户端: 服务器端代码: ```python import socket import threading # 创建一个socket对象 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 获取本地主机名和端口号 host = socket.gethostname() port = 9999 # 绑定端口号 server_socket.bind((host, port)) # 设置最大连接数,超过后排队 server_socket.listen(5) # 存储所有客户端socket连接 client_sockets = [] # 存储所有客户端名称 client_names = [] def broadcast(msg, sender): """ 广播消息给所有客户端 """ for client in client_sockets: if client != sender: try: client.send(msg.encode()) except: # 如果发送失败,则说明该客户端已经断开连接,需要将其从列表中移除 index = client_sockets.index(client) client_sockets.remove(client) client.close() name = client_names[index] client_names.remove(name) print(f"Disconnected from {name}") broadcast(f"{name} has left the chat room.", server_socket) def handle_client(client_socket): """ 处理每个客户端的连接 """ while True: try: msg = client_socket.recv(1024).decode() broadcast(msg, client_socket) except: # 如果接收失败,则说明该客户端已经断开连接,需要将其从列表中移除 index = client_sockets.index(client_socket) client_sockets.remove(client_socket) client_socket.close() name = client_names[index] client_names.remove(name) print(f"Disconnected from {name}") broadcast(f"{name} has left the chat room.", server_socket) break while True: # 等待客户端连接 client_socket, client_address = server_socket.accept() print(f"Connected from {client_address}") client_socket.send("Enter your name:".encode()) # 接收客户端名称 name = client_socket.recv(1024).decode() client_names.append(name) client_sockets.append(client_socket) print(f"Client name is {name}") broadcast(f"{name} has joined the chat room.", server_socket) client_socket.send("Welcome to the chat room. Type 'exit' to leave.".encode()) # 创建一个新线程,处理该客户端的连接 client_thread = threading.Thread(target=handle_client, args=(client_socket,)) client_thread.start() ``` 客户端代码: ```python import socket import threading # 创建一个socket对象 client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 获取本地主机名和端口号 host = socket.gethostname() port = 9999 # 连接服务器 client_socket.connect((host, port)) # 接收服务器发送的欢迎消息 msg = client_socket.recv(1024).decode() print(msg) # 输入客户端名称 name = input() client_socket.send(name.encode()) # 接收服务器发送的欢迎消息 msg = client_socket.recv(1024).decode() print(msg) def receive(): """ 接收服务器发送的消息 """ while True: try: msg = client_socket.recv(1024).decode() print(msg) except: # 如果接收失败,则说明服务器断开了连接,需要退出程序 client_socket.close() print("Disconnected from the server.") break def send(): """ 发送消息给服务器 """ while True: msg = input() client_socket.send(msg.encode()) if msg == "exit": client_socket.close() break # 创建两个线程,分别处理接收和发送 receive_thread = threading.Thread(target=receive) receive_thread.start() send_thread = threading.Thread(target=send) send_thread.start() ``` 使用方法: 1. 运行服务器端代码 2. 运行多个客户端代码,输入不同的名称 3. 在客户端之间互相发送消息,所有客户端都可以看到消息 4. 输入"exit"退出聊天室
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值