您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 信息化管理 > 基于MFC的局域网聊天工具
基于MFC的局域网聊天工具用Socket做一个局域网聊天工具程序设计成为简单的服务端和客户端之间的通信,但通过一些方法可以将这两者进行统一起来,让服务端也成为客户端,让客户端也成为服务端,使它们之间可以互相随时不间断的通信.考虑到实现最原始的服务端和客户端之间的通信所需要的步骤对于写这样的程序是很有帮助的.作为服务端,要声明一个SocketA并绑定(Bind)某一个IP+这个IP指定的通信端口,比如这个是127.0.0.1:9050,然后开始监听(Listen),Listen可以监听来自多个IP传过来的连接请求,具体可以同时连接几个客户端,Listen方法中可以设定一个参数.如果Listen到某一个客户端发来连接请求了,这时定义一个新的SocketB专门负责与这个客户端的通信,SocketB=A.Accept().这时可以获取这个客户端的IP和端口,IPEndPointC=(IPEndPoint)B.RemoteEndPoint,C.Address和C.Port分别表示客户端C的IP地址和端口.这时通过B.Send()方法就可以给C发送消息了,B.Receive()可以接收客户端C发来的信息.作为客户端,也需要声明一个SocketD并绑定某一个IP+本机一个未被占用的端口,定义IPEndPointE表示要进行连接的服务端Socket,要指明E的IP和端口,这样才可以进行端口对端口之间的通信,接下来就可以尝试D.Connect(E),连接成功之后就可以发送和接收数据了,D.Send(),D.Receive.发送消息时,数据都是以字节或字节数组为单位进行传输的,比如我客户端D要发送HelloWorld则要这样写:D.Send(Encoding.ASCII.GetBytes(HelloWorld)).接受消息时,也是以字节或字节数组,比如服务端要接受D刚才发送的HelloWorld,可以这样写:Byte[]data=newByte[1024];intreceivedDataLength=B.Receive(data);stringstringdata=Encoding.ASCII.GetString(data,0,receivedDataLength);stringdata这时就是HelloWorld.上面只是大概的阐述了服务端与客户端之间的通信过程,在网上找到了具体的代码例子,也贴过来参考参考.这个例子没有将服务端与客户端统一起来,他是分别写服务端和客户端的.服务端代码usingSystem;usingSystem;usingSystem.Net;usingSystem.Net.Sockets;usingSystem.Text;namespacetcpserver{///summary///Class1的摘要说明。////summaryclassserver{///summary///应用程序的主入口点。////summary[STAThread]staticvoidMain(string[]args){////TODO:在此处添加代码以启动应用程序//intrecv;//用于表示客户端发送的信息长度byte[]data;//=newbyte[1024];//用于缓存客户端所发送的信息,通过socket传递的信息必须为字节数组IPEndPointipep=newIPEndPoint(IPAddress.Any,9050);//本机预使用的IP和端口Socketnewsock=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);newsock.Bind(ipep);//绑定newsock.Listen(10);//监听Console.WriteLine(waitingforaclient);Socketclient=newsock.Accept();//当有可用的客户端连接尝试时执行,并返回一个新的socket,用于与客户端之间的通信IPEndPointclientip=(IPEndPoint)client.RemoteEndPoint;Console.WriteLine(connectwithclient:+clientip.Address+atport:+clientip.Port);stringwelcome=welcomehere!;data=Encoding.ASCII.GetBytes(welcome);client.Send(data,data.Length,SocketFlags.None);//发送信息while(true){//用死循环来不断的从客户端获取信息data=newbyte[1024];recv=client.Receive(data);Console.WriteLine(recv=+recv);if(recv==0)//当信息长度为0,说明客户端连接断开break;Console.WriteLine(Encoding.ASCII.GetString(data,0,recv));client.Send(data,recv,SocketFlags.None);}Console.WriteLine(Disconnectedfrom+clientip.Address);client.Close();newsock.Close();}}}客户端代码usingSystem;usingSystem.Net;usingSystem.Net.Sockets;usingSystem.Text;namespacetcpclient{///summary///Class1的摘要说明。////summaryclassclient{///summary///应用程序的主入口点。////summary[STAThread]staticvoidMain(string[]args){////TODO:在此处添加代码以启动应用程序//byte[]data=newbyte[1024];Socketnewclient=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);newclient.Bind(newIPEndPoint(IPAddress.Any,905));Console.Write(pleaseinputtheserverip:);stringipadd=Console.ReadLine();Console.WriteLine();Console.Write(pleaseinputtheserverport:);intport=Convert.ToInt32(Console.ReadLine());IPEndPointie=newIPEndPoint(IPAddress.Parse(ipadd),port);//服务器的IP和端口try{//因为客户端只是用来向特定的服务器发送信息,所以不需要绑定本机的IP和端口。不需要监听。newclient.Connect(ie);}catch(SocketExceptione){Console.WriteLine(unabletoconnecttoserver);Console.WriteLine(e.ToString());return;}intreceivedDataLength=newclient.Receive(data);stringstringdata=Encoding.ASCII.GetString(data,0,receivedDataLength);Console.WriteLine(stringdata);while(true){stringinput=Console.ReadLine();if(input==exit)break;newclient.Send(Encoding.ASCII.GetBytes(input));data=newbyte[1024];receivedDataLength=newclient.Receive(data);stringdata=Encoding.ASCII.GetString(data,0,receivedDataLength);Console.WriteLine(stringdata);}Console.WriteLine(disconnectfromsercer);newclient.Shutdown(SocketShutdown.Both);newclient.Close();}}}上面的服务端和客户端都是控制台应用程序,想办法做一个窗体类型的,思路就是另起一个线程,这个线程专门负责两端建立连接.如果不采用另起线程的方法,当等待连接而没有连接上,或者主动连接,服务端还没有相应时,程序就会出现没有响应的假死状态.当这个线程将两个端口连接成功后,就让程序进入一个死循环,这个死循环负责不断的接收是否有消息传来,传来的话就在txtGetMsg中显示出来:while(true)//用死循环来不断的获取信息{data=newbyte[1024];recv=newclient.Receive(data);uiContext.Send(newSendOrPostCallback(state={inttxtGetMsgLength=txtGetMsg.Text.Length;stringrecMsg=Friend:+System.DateTime.Now.ToString()+\n+Encoding.Unicode.GetString(data,0,recv)+\n;txtGetMsg.AppendText(recMsg);txtGetMsg.Select(txtGetMsgLength,recMsg.Length-Encoding.Unicode.GetString(data,0,recv).Length-1);txtGetMsg.SelectionColor=Color.Red;}),null);}如果按下发送消息的按钮,则发送txtSendMsg中的文本,我写的是用Unicode编码,所以可以发送中文字符.privatevoidbtnSendMsg_Click(objectsender,EventArgse){stringinput=txtSendMsg.Text;if(input==){MessageBox.Show(消息不能为空!,发送消息出错);txtSendMsg.Focus();}else{if(meIsClient){newclient.Send(Encoding.Unicode.GetBytes(input));stringshowText=Me:+System.DateTime.Now.ToString()+\n+input+\n;inttxtGetMsgLength=txtGetMsg.Text.Length;txtGetMsg.AppendText(showText);txtGetMsg.Select(txtGetMsgLength,showText.Length-1-input.Length);txtGetMsg.SelectionColor=Color.Blue;txtSendMsg.Text=;}else{client.Send(Encoding.Unicode.GetBytes(input));stringshowText=Me+System.DateTime.Now.ToString()+\n+input+\n;inttxtGetMsgLength=txtGetMsg.Text.Length;txtGetMsg.AppendText(showText);txtGetMsg.Select(txtGetMsgLength,showText.Length-1-input.Leng
本文标题:基于MFC的局域网聊天工具
链接地址:https://www.777doc.com/doc-2570871 .html