TCPserver客户端

Imports System.Net
Imports System.Net.Sockets
Imports System
Imports System.Threading
Imports System.IO


Public Class ChatServer
    Implements IDisposable


#Region "自定义变量"


    Private ReadOnly ServerIP As IPAddress
    Private ReadOnly PortNum As Integer = 5000
    Private ReadOnly ServerTag As String


    Private SocketList As New ArrayList
    Private MySocket As Socket = Nothing
    Private listener As TcpListener
    Private SocketStream As NetworkStream
    Private Writer As BinaryWriter
    Private Reader As BinaryReader
    Private NewThread As Thread = Nothing


    Private IsStarted As Boolean = False  '服务器状态为未启动
    Private ClientCount As Integer = 0
    Const CMAXCOUNT = 30 '容许连接的最大客户端数目




    Public Event OnText(ByVal N As Integer, ByVal msg As String)
    Private Index As Integer
    Public ClientRemoteEndPoint As String


#End Region


#Region "初始化服务器端口参数"


    ''' <summary>
    ''' 初始化服务器端口参数
    ''' </summary>
    Sub New(ByVal SerIP As IPAddress, ByVal Port As Integer, ByVal SerTag As String)
        ServerIP = SerIP
        PortNum = Port
        ServerTag = SerTag
    End Sub


#End Region


#Region "属性区域"


    ''' <summary>
    ''' 服务器连接状态
    ''' </summary>
    Public ReadOnly Property IsConnected() As Boolean
        Get
            Return IsStarted
        End Get
    End Property


#End Region


#Region "自定义过程"


    ''' <summary>
    ''' 创建服务器
    ''' </summary>
    Public Sub Start()
        Try
            '创建一个侦听对象
            listener = New TcpListener(ServerIP, PortNum)
            '启动服务器侦听端口
            listener.Start()
            IsStarted = True
            RaiseEvent OnText(3, "服务器已启动")
            While True
                '连接客户端,返回一个 套接字
                If ClientCount <= CMAXCOUNT Then
                    MySocket = listener.AcceptSocket()
                    '添加到连接列表中
                    SocketList.Add(MySocket)
                    ClientRemoteEndPoint = MySocket.RemoteEndPoint.ToString()
                    RaiseEvent OnText(1, ClientRemoteEndPoint)
                    SocketStream = New NetworkStream(MySocket)
                    Writer = New BinaryWriter(SocketStream)
                    '通知客户端,连接成功
                    ' Writer.Write("与服务器成功连接" & vbCrLf) '应该在什么时候断开该连接
                    Writer.Write("EB90")
                    Writer.Flush()
                    ClientCount += 1
                Else
                    MySocket = listener.AcceptSocket()
                    SocketStream = New NetworkStream(MySocket)
                    Writer = New BinaryWriter(SocketStream)
                    '通知客户端,连接成功
                    Writer.Write("Server>>  服务器的连接数已满,连接已经断开")
                    '  MySocket.Disconnect(False) '断开连接
                    MySocket.Close()
                End If
            End While
        Catch ex As Exception
            IsStarted = False
            If listener IsNot Nothing Then listener.Stop()
            listener = Nothing
            RaiseEvent OnText(3, "服务器启动失败,请检查网络。")
            ' MsgBox(ex.ToString)
        Finally
            SocketStream = Nothing
            Writer = Nothing
            MySocket = Nothing
        End Try
    End Sub


    ''' <summary>
    ''' 该方法在每个实例中仅容许使用一次
    ''' </summary>
    Public Sub Connect()
        If Not IsStarted Then
            Try
                '创建新线程,用新的线程启动服务器
                NewThread = New Thread(New ThreadStart(AddressOf Start))
                NewThread.Name = "Thread for sever start"
                NewThread.Start()
                '  Catch ex As ThreadStartException
            Catch ex As Exception
                MsgBox(ex.Message, MsgBoxStyle.OkOnly, "线程启动错误")
                '线程创建失败时服务器启动失败
            End Try
        Else
            MsgBox("该实例中已经有一个服务器进程在运行,若要创建新的服务器请使用其它实例", _
             MsgBoxStyle.OkOnly, "警告")
        End If


    End Sub


    ''' <summary>
    ''' 断开一个连接
    ''' </summary>
    Public Sub Disconnect(ByVal index As Integer)
        Try
            Dim con As Socket = SocketList(index)
            If con IsNot Nothing Then
                SocketList.RemoveAt(index)
                ClientCount -= 1
                RaiseEvent OnText(2, con.RemoteEndPoint.ToString)
                RaiseEvent OnText(3, con.RemoteEndPoint.ToString & " - 连接断开")
                con.Close()
            End If
        Catch ex As Exception
            MsgBox("操作错误")
        End Try
    End Sub


    ''' <summary>
    ''' 服务器连接断开
    ''' </summary>
    Public Sub Close()
        Try
            If MySocket IsNot Nothing Then MySocket.Close()
            If listener IsNot Nothing Then listener.Stop()
        Catch ex As Exception


        End Try
    End Sub
    ''' <summary>
    ''' 发消息给指定客户端
    ''' </summary>
    Public Sub SendMsg(ByVal index As Integer, ByVal msg As String)
        Dim Con As Socket
        Dim SocketStream As NetworkStream
        Dim SentMsg As BinaryWriter
        Try
            Con = SocketList(index)
            SocketStream = New NetworkStream(Con)
            SentMsg = New BinaryWriter(SocketStream)
            SentMsg.Write(msg)         '发送信息
            RaiseEvent OnText(3, "发送数据成功")
        Catch ex As IndexOutOfRangeException
            RaiseEvent OnText(3, "发送数据失败")
            MsgBox(ex.Message, MsgBoxStyle.OkOnly, "越界异常")
        Finally
            Con = Nothing
            SocketStream = Nothing
            SentMsg = Nothing
        End Try
    End Sub


    ''' <summary>
    ''' 发消息给所有客户端
    ''' </summary>
    Public Sub SendMsg(Optional ByVal msg As String = "")
        Dim Con As Socket
        Dim SocketStream As NetworkStream
        Dim SentMsg As BinaryWriter
        Try
            If SocketList.Count > 0 Then
                For Index = 0 To SocketList.Count - 1
                    Try
                        Con = SocketList(Index)
                        If Con Is Nothing Then
                            Thread.Sleep(300)
                            Continue For
                        End If
                        SocketStream = New NetworkStream(Con)
                        SentMsg = New BinaryWriter(SocketStream)
                        SentMsg.Write(msg)         '发送信息
                    Catch ex As IOException
                        SocketList.RemoveAt(Index)
                        ClientCount -= 1
                        If Con IsNot Nothing Then
                            RaiseEvent OnText(2, Con.RemoteEndPoint.ToString)
                            RaiseEvent OnText(3, Con.RemoteEndPoint.ToString & " - 连接断开")
                            RaiseEvent OnText(3, "发送数据给所有客户时失败")
                        End If


                        Exit Sub
                    Finally
                        Con = Nothing
                        SocketStream = Nothing
                        SentMsg = Nothing
                    End Try
                    Thread.Sleep(300)
                Next
                If msg = "" Then
                    RaiseEvent OnText(3, "自动发送数据给所有客户成功")
                Else
                    RaiseEvent OnText(3, "发送数据给所有客户成功")
                End If
            End If
            Thread.Sleep(300)
        Catch ex As Exception
            RaiseEvent OnText(3, "发送数据给所有客户时失败")
        End Try


    End Sub


    ''' <summary>
    ''' 接收客户的客户端消息
    ''' </summary>
    Public Function RecvieMsg() As String
        Dim msg As String = ""
        Dim Con As Socket
        Dim SStream As NetworkStream


        Dim i As Short
        Try
            For i = 0 To SocketList.Count - 1
                Con = SocketList.Item(i)
                If Con Is Nothing OrElse Not Con.Connected Then
                    Exit For
                End If
                If Con.Available = 0 Then
                    Thread.Sleep(30)
                    Continue For
                End If
                SStream = New NetworkStream(Con)
                Reader = New BinaryReader(SStream)
                Try
                    msg = Reader.ReadString
                    Return msg


                Catch ex As SocketException
                    MsgBox(ex.Message)
                Finally
                    Reader = Nothing
                    SStream = Nothing
                    Con = Nothing
                End Try
                Thread.Sleep(30)
            Next
        Catch ex As Exception


        End Try


        Return Nothing
    End Function


#End Region


    Public Shared Function GetMyFirstIPAddress()
        Try
            Dim MyHostName As String = System.Net.Dns.GetHostName()
            Dim MyIPEntry As System.Net.IPHostEntry = System.Net.Dns.GetHostEntry(MyHostName)
            Dim MyAddresses() As System.Net.IPAddress = MyIPEntry.AddressList
            Dim IP As String
            For Each MyIP As System.Net.IPAddress In MyAddresses
                IP = MyIP.ToString()
                Dim temp() As String = IP.Split(".")
                ' Debug.Print(temp.Length)
            Next
            Return IP
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
        Return DBNull.Value
    End Function


#Region "IDisposable Support"
    Private disposedValue As Boolean ' 检测冗余的调用
    ' IDisposable
    Protected Overridable Sub Dispose(ByVal disposing As Boolean)
        If Not Me.disposedValue Then
            If disposing Then
                ' TODO: 释放托管状态(托管对象)。
                If MySocket IsNot Nothing Then MySocket.Close()
                If listener IsNot Nothing Then listener.Stop()
                SocketList = Nothing
                MySocket = Nothing
                SocketStream = Nothing
                Writer = Nothing
                Reader = Nothing
                NewThread = Nothing
                listener = Nothing
                IsStarted = False
                ClientCount = 0
            End If


            ' TODO: 释放非托管资源(非托管对象)并重写下面的 Finalize()。
            ' TODO: 将大型字段设置为 null。
        End If
        Me.disposedValue = True
    End Sub


    ' TODO: 仅当上面的 Dispose(ByVal disposing As Boolean)具有释放非托管资源的代码时重写 Finalize()。
    'Protected Overrides Sub Finalize()
    '    ' 不要更改此代码。请将清理代码放入上面的 Dispose(ByVal disposing As Boolean)中。
    '    Dispose(False)
    '    MyBase.Finalize()
    'End Sub


    ' Visual Basic 添加此代码是为了正确实现可处置模式。
    Public Sub Dispose() Implements IDisposable.Dispose
        ' 不要更改此代码。请将清理代码放入上面的 Dispose(ByVal disposing As Boolean)中。
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub
#End Region


End Class
### 回答1: 在Linux环境下使用C语言编写一个TCP服务器来处理多个客户端的连接是很常见的需求。以下是一个基本的实现示例: 首先,我们需要创建一个服务器套接字,监听指定的端口。然后,我们需要使用`select`函数来实现多客户端的处理。`select`函数会阻塞直到某个套接字上有可读或可写的数据时才返回,我们可以利用这一特性来处理多个客户端的连接。 为了支持多个客户端,我们需要维护一个客户端套接字的集合,用于存储当前连接的客户端。每当有新的客户端连接到服务器时,我们将其套接字添加到这个集合中。 然后,我们使用`select`函数来监视所有的套接字,包括服务器套接字和客户端套接字。当`select`函数返回时,我们可以通过检查文件描述符集合中的每个套接字来确定哪个套接字上有可读或可写的数据。如果是服务器套接字上有可读的数据,表示有新的客户端请求连接,我们接受这个连接并将其套接字添加到客户端集合中。如果是客户端套接字上有可读的数据,表示客户端发送了数据,我们可以处理这些数据。如果是客户端套接字上有可写的数据,表示服务器可以向客户端发送数据。 在处理数据时,我们可以使用`recv`函数来接收来自客户端数据,然后根据实际需求进行处理,比如打印或保存数据。如果需要向客户端发送数据,可以使用`send`函数来发送数据。 以上就是基于Linux下C语言实现多客户端TCP服务器的基本思路。需要注意的是,在实际的代码实现中,还需要处理一些异常情况,例如客户端断开连接时的处理。此外,还可以使用多线程或多进程来处理多个客户端的同时连接,以提高服务器的性能和并发处理能力。 ### 回答2: 在Linux C中,可以使用TCP服务器来处理多个客户端连接。以下是一个简单的示例代码: 1. 首先,创建一个套接字(socket)来监听客户端连接请求: ```c int sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd == -1) { perror("socket"); exit(EXIT_FAILURE); } struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_port = htons(PORT); // 设置端口号 server_addr.sin_addr.s_addr = htonl(INADDR_ANY); // 监听所有网络接口 if (bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) { perror("bind"); exit(EXIT_FAILURE); } listen(sockfd, BACKLOG); // 启动监听 ``` 2. 使用循环等待客户端连接: ```c while(1) { struct sockaddr_in client_addr; socklen_t addr_len = sizeof(client_addr); int client_fd = accept(sockfd, (struct sockaddr*)&client_addr, &addr_len); if (client_fd == -1) { perror("accept"); exit(EXIT_FAILURE); } printf("Accept a connection from %s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); // 在接受到客户端连接后,可以fork()一个子进程来处理该客户端,或者使用线程、多路复用等方式来处理多个客户端 // ... } ``` 3. 在处理连接后,可以进行相应的数据交互,如接收和发送数据,以及关闭连接等操作。 ```c // 读取客户端发送的数据 char buffer[MAX_BUFFER_SIZE]; int num_bytes = recv(client_fd, buffer, sizeof(buffer), 0); if (num_bytes == -1) { perror("recv"); exit(EXIT_FAILURE); } // 处理数据 // ... // 发送响应给客户端 char response[] = "Hello, client!"; if (send(client_fd, response, sizeof(response), 0) == -1) { perror("send"); exit(EXIT_FAILURE); } // 关闭与客户端的连接 close(client_fd); ``` 这是一个简单的多客户端TCP服务器的实现代码。当然,在实际应用中,可能需要处理更多的异常情况,如错误处理、客户端连接超时、并发访问等。同时,还可以使用线程池、epoll等技术来提高服务器的性能和并发处理能力。 ### 回答3: 在Linux C编程中,可以通过创建一个TCP服务器来处理多个客户端的连接请求。 首先,我们需要创建一个套接字,使用`socket()`函数,指定使用TCP协议,得到一个用于监听的套接字描述符。 ```c int serverSocket = socket(AF_INET, SOCK_STREAM, 0); ``` 然后,我们需要给服务器绑定一个地址和端口号,使用`bind()`函数,将套接字与特定的IP地址和端口号绑定。 ```c struct sockaddr_in serverAddress; serverAddress.sin_family = AF_INET; serverAddress.sin_port = htons(PORT); serverAddress.sin_addr.s_addr = INADDR_ANY; bind(serverSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress)); ``` 接下来,我们需要设置服务器监听队列的最大长度,使用`listen()`函数。 ```c listen(serverSocket, BACKLOG); ``` 现在,我们正式进入了服务器的工作循环,接受客户端的连接请求。 ```c while(1) { int clientSocket = accept(serverSocket, NULL, NULL); // 这里可以创建子进程或线程来处理客户端的连接 // 或使用非阻塞IO或异步IO来实现并发处理多个客户端 // 读取客户端发送的数据 char buffer[BUFFER_SIZE]; int bytesRead = recv(clientSocket, buffer, sizeof(buffer), 0); // 处理接收到的数据 // 发送数据客户端 char response[] = "Hello, client!"; send(clientSocket, response, strlen(response), 0); // 关闭与客户端的连接 close(clientSocket); } ``` 以上就是一个简单的Linux C TCP服务器客户端的实现。在实际应用中,可能需要使用多线程、多进程、非阻塞IO或者异步IO等技术来提高服务器的并发处理能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值