C语言问题:局域网聊天系统中的服务器怎么区分不同的客户端并把数据传给客户端?

C语言问题:局域网聊天系统中的服务器怎么区分不同的客户端并把数据传给客户端?,第1张

通常服务器是这样的:

struct sockaddr clientAddr

int ret = accept(s,&clientAddr,sizeof(struct sockaddr))

if(ret >0)

{

....

}

SOCKET PASCAL accept( SOCKET s, struct sockaddr * addr,int * addrlen)

请看accept原型 第2个参数为指针 。也就是如果accept成功 那么服务器端就会得到客户端的struct sockaddr结构体数据,里面包含了客户的ip port等。

实际中要区分的话,应该是有类似于自拟协议,比如约定好,客户端连上服务器后,主动发送包含身份的信息给服务器,服务器识别后,才开始为该客户服务。

using System

using System.Collections.Generic

using System.Net

using System.Net.Sockets

using System.Threading

using System.Text

using System.IO

class Server

{

    Socket _listenSocket

    Dictionary<string, ClientProcess> _clients

    public Server(int port)

    {

        _clients = new Dictionary<string, ClientProcess>()

        _listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)

        IPEndPoint lep = new IPEndPoint(IPAddress.Any, port)

        _listenSocket.Bind(lep)

    }

    public void Start()

    {

        _listenSocket.Listen(5)

        for (  )

        {

            Socket client = _listenSocket.Accept()

            ClientProcess cp = new ClientProcess(this, client)

            ThreadStart ts = new ThreadStart(cp.Process)

            Thread t = new Thread(ts)

            t.Start()

        }

    }

    public void AddClient(string email, ClientProcess c)

    {

        lock (_clients)

        {

            if (!_clients.ContainsKey(email))

                _clients.Add(email, c)

        }

    }

    public void RemoveClient(string email)

    {

        lock (_clients)

        {

            if (_clients.ContainsKey(email))

                _clients.Remove(email)

        }

    }

    public void SendTo(string from, string email, string msg)

    {

        ClientProcess cp

        lock(_clients) {

            _clients.TryGetValue(email, out cp)

        }

        if (cp != null)

        {

            cp.Send(from, msg)

        }

    }

}

class ClientProcess

{

    Server _serv

    Socket _s

    TcpClient _tc

    StreamReader _sr

    StreamWriter _sw

    string email

    public ClientProcess(Server serv, Socket s)

    {

        _serv = serv

        _s = s

        _tc = new TcpClient()

        _tc.Client = _s

        _sr = new StreamReader(_tc.GetStream())

        _sw = new StreamWriter(_tc.GetStream())

    }

    public void Process()

    {

        try

        {

            email = _sr.ReadLine()

            _serv.AddClient(email, this)

            for (  )

            {

                string l = _sr.ReadLine()

                int i = l.IndexOf(':')

                if(i == -1)    

                    continue

                string em = l.Substring(0, i)

                string msg = l.Substring(i + 1)

                _serv.SendTo(email, em, msg)

            }

        }

        catch

        {

            _serv.RemoveClient(email)

        }

    }

    public void Send(string email, string msg)

    {

        _sw.WriteLine("{0}:{1}", email, msg)

        _sw.Flush()

    }

}

class Program

{

    static void Main(string[] args)

    {

        Server s = new Server(12345)

        s.Start()

    }

}

协议是这样的:

1、发送和接收都是以行为单位的

2、客户端连接后发送的第一行数据是自己的邮箱

3、客户端之后发送的格式是:  对方邮箱 冒号 要发送的消息。冒号是英文半角冒号,邮箱和冒号间没有空格


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/251087.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-14
下一篇2023-04-14

发表评论

登录后才能评论

评论列表(0条)

    保存