Tcpclient简单聊天程序
Posted 花叶两不见
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Tcpclient简单聊天程序相关的知识,希望对你有一定的参考价值。
以前C/S通讯这一块都是基于套接字(Sockets)编程,但是面对业务逻辑复杂的C/S系统,通讯这一块往往都是被封装好了的,前几天写的一个小小窗体聊天程序,主要是练习一下C#封装的TcpListener、TcpClient以及NetworkStream的使用,直接看图上代码:
- using System;
- using System.Drawing;
- using System.Collections;
- using System.ComponentModel;
- using System.Windows.Forms;
- using System.Data;
- using System.Net;
- using System.Net.Sockets;
- using System.Threading;
- using System.IO;
- namespace ChartTestServer
- {
- public partial class Form1 : Form
- {
- public Form1()
- {
- InitializeComponent();
- }
- private NetworkStream networkStream;
- private StreamReader streamReader;
- private StreamWriter streamWriter;
- private Socket socketForClient;
- private TcpListener tcpListener;
- private Thread serverThread;// 启动服务线程
- private Thread recvThread;// 接收信息线程
- private void button1_Click(object sender, EventArgs e)
- {
- serverThread = new Thread(new ThreadStart(Listen));
- serverThread.Start();
- }
- //[STAThread]
- private void Listen()
- {
- try
- {
- Int32 port = Int32.Parse(txtPort.Text);
- IPAddress ipAddress = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0];
- tcpListener = new TcpListener(ipAddress, port);
- // 开始侦听
- tcpListener.Start();
- listBox1.Items.Add("服务已经启动!");
- button1.Enabled = false;
- button2.Enabled = true;
- // 返回可以用以处理连接的Socket实例
- socketForClient = tcpListener.AcceptSocket();
- // 如果返回值是"true",则产生的套节字已经接受来自远方的连接请求
- if (socketForClient.Connected)
- {
- button3.Enabled = true;
- listBox1.Items.Add("客户端成功连接上服务器!");
- // 创建networkStream对象通过网络套节字来接受和发送数据
- networkStream = new NetworkStream(socketForClient);
- // 从当前数据流中读取一行字符,返回值是字符串
- streamReader = new StreamReader(networkStream);
- streamWriter = new StreamWriter(networkStream);
- recvThread = new Thread(new ThreadStart(RecvData));
- recvThread.Start();
- }
- }
- catch (Exception exc)
- {
- MessageBox.Show(exc.Message, "Server提示");
- }
- }
- // 接收服务器发来的信息
- private void RecvData()
- {
- string msg = streamReader.ReadLine();
- // 如果不是接收到客户端发来的退出信息,则不断接收信息
- while (!msg.Equals("exit"))
- {
- //statusChart1.Value = Convert.ToInt32(msg);
- listBox1.Items.Add("收到信息: " + msg);
- msg = streamReader.ReadLine();
- }
- // 如果接收到客户的退出信息,则退出服务
- button1.Enabled = true;
- button2.Enabled = false;
- button3.Enabled = false;
- listBox1.Items.Add("客户已经关闭");
- listBox1.Items.Add("服务器关闭");
- // 关闭资源
- ReleaseResource();
- }
- private void button3_Click(object sender, EventArgs e)
- {
- Thread sendThread = new Thread(new ThreadStart(SendData));
- sendThread.Start();
- }
- private void SendData()
- {
- if (txtMsg.Text != "")
- {
- listBox1.Items.Add("发送信息: " + txtMsg.Text);
- // 往当前的数据流中写入一行字符串
- streamWriter.WriteLine(txtMsg.Text);
- // 刷新当前数据流中的数据
- streamWriter.Flush();
- txtMsg.Text = ""; // 清空
- }
- else
- {
- MessageBox.Show("发送信息不能为空","提示");
- }
- }
- private void button2_Click(object sender, EventArgs e)
- {
- try
- {
- if (button3.Enabled == true)
- {
- // 停止服务后,允许 启动服务,但是不允许发送消息
- button1.Enabled = true;
- button2.Enabled = false;
- button3.Enabled = false;
- string exitMsg = "exit"; // 要退出时,发送 exit 信息给客户端
- streamWriter.WriteLine(exitMsg);
- // 刷新当前数据流中的数据
- streamWriter.Flush();
- listBox1.Items.Add("服务器关闭");
- // 释放资源
- recvThread.Abort();
- ReleaseResource();
- }
- else
- {
- // 停止服务后,允许 启动服务,但是不允许发送消息
- button1.Enabled = true;
- button2.Enabled = false;
- button3.Enabled = false;
- listBox1.Items.Add("服务器关闭");
- // 关闭TCP连接,关闭线程
- tcpListener.Stop();
- serverThread.Abort();
- }
- }
- catch (Exception exc)
- {
- MessageBox.Show(exc.Message, "Server提示");
- }
- }
- // 释放资源
- private void ReleaseResource()
- {
- networkStream.Close();
- streamReader.Close();
- streamWriter.Close();
- socketForClient.Shutdown(SocketShutdown.Both);
- socketForClient.Close();
- tcpListener.Stop();
- }
- private void Form1_FormClosing(object sender, FormClosingEventArgs e)
- {
- // 在未停止 服务 前,不允许关闭窗体
- if (button1.Enabled == false)
- {
- MessageBox.Show("请先停止服务!", "Server提示");
- e.Cancel = true;
- }
- }
- private void Form1_Load(object sender, EventArgs e)
- {
- // 在没有启动服务器之前,不允许停止服务以及发送信息
- button2.Enabled = false;
- button3.Enabled = false;
- }
- }
- using System;
- using System.Drawing;
- using System.Collections;
- using System.ComponentModel;
- using System.Windows.Forms;
- using System.Data;
- using System.Net;
- using System.Net.Sockets;
- using System.Threading;
- using System.IO;
- namespace ChartTestServer
- {
- public partial class Form1 : Form
- {
- public Form1()
- {
- InitializeComponent();
- }
- private NetworkStream networkStream;
- private StreamReader streamReader;
- private StreamWriter streamWriter;
- private Socket socketForClient;
- private TcpListener tcpListener;
- private Thread serverThread; // 启动服务线程
- private Thread recvThread;// 接收信息线程
- private void button1_Click(object sender, EventArgs e)
- {
- serverThread = new Thread(new ThreadStart(Listen));
- serverThread.Start();
- }
- //[STAThread]
- private void Listen()
- {
- try
- {
- Int32 port = Int32.Parse(txtPort.Text);
- IPAddress ipAddress = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0];
- tcpListener = new TcpListener(ipAddress, port);
- // 开始侦听
- tcpListener.Start();
- listBox1.Items.Add("服务已经启动!");
- button1.Enabled = false;
- button2.Enabled = true;
- // 返回可以用以处理连接的Socket实例
- socketForClient = tcpListener.AcceptSocket();
- // 如果返回值是"true",则产生的套节字已经接受来自远方的连接请求
- if (socketForClient.Connected)
- {
- button3.Enabled = true;
- listBox1.Items.Add("客户端成功连接上服务器!");
- // 创建networkStream对象通过网络套节字来接受和发送数据
- networkStream = new NetworkStream(socketForClient);
- // 从当前数据流中读取一行字符,返回值是字符串
- streamReader = new StreamReader(networkStream);
- streamWriter = new StreamWriter(networkStream);
- recvThread = new Thread(new ThreadStart(RecvData));
- recvThread.Start();
- }
- }
- catch (Exception exc)
- {
- MessageBox.Show(exc.Message, "Server提示");
- }
- }
- // 接收服务器发来的信息
- private void RecvData()
- {
- string msg = streamReader.ReadLine();
- // 如果不是接收到客户端发来的退出信息,则不断接收信息
- while (!msg.Equals("exit"))
- {
- //statusChart1.Value = Convert.ToInt32(msg);
- listBox1.Items.Add("收到信息: " + msg);
- msg = streamReader.ReadLine();
- }
- // 如果接收到客户的退出信息,则退出服务
- button1.Enabled = true;
- button2.Enabled = false;
- button3.Enabled = false;
- listBox1.Items.Add("客户已经关闭");
- listBox1.Items.Add("服务器关闭");
- // 关闭资源
- ReleaseResource();
- }
- private void button3_Click(object sender, EventArgs e)
- {
- Thread sendThread = new Thread(new ThreadStart(SendData));
- sendThread.Start();
- }
- private void SendData()
- {
- if (txtMsg.Text != "")
- {
- listBox1.Items.Add("发送信息: " + txtMsg.Text);
- // 往当前的数据流中写入一行字符串
- streamWriter.WriteLine(txtMsg.Text);
- // 刷新当前数据流中的数据
- streamWriter.Flush();
- txtMsg.Text = ""; // 清空
- }
- else
- {
- MessageBox.Show("发送信息不能为空", "提示");
- }
- }
- private void button2_Click(object sender, EventArgs e)
- {
- try
- {
- if (button3.Enabled == true)
- {
- // 停止服务后,允许 启动服务,但是不允许发送消息
- button1.Enabled = true;
- button2.Enabled = false;
- button3.Enabled = false;
- string exitMsg = "exit"; // 要退出时,发送 exit 信息给客户端
- streamWriter.WriteLine(exitMsg);
- // 刷新当前数据流中的数据
- streamWriter.Flush();
- listBox1.Items.Add("服务器关闭");
- // 释放资源
- recvThread.Abort();
- ReleaseResource();
- }
- else
- {
- // 停止服务后,允许 启动服务,但是不允许发送消息
- button1.Enabled = true;
- button2.Enabled = false;
- button3.Enabled = false;
- listBox1.Items.Add("服务器关闭");
- // 关闭TCP连接,关闭线程
- tcpListener.Stop();
- serverThread.Abort();
- }
- }
- catch (Exception exc)
- {
- MessageBox.Show(exc.Message, "Server提示");
- }
- }
- // 释放资源
- private void ReleaseResource()
- {
- networkStream.Close();
- streamReader.Close();
- streamWriter.Close();
- socketForClient.Shutdown(SocketShutdown.Both);
- socketForClient.Close();
- tcpListener.Stop();
- }
- private void Form1_FormClosing(object sender, FormClosingEventArgs e)
- {
- // 在未停止 服务 前,不允许关闭窗体
- if (button1.Enabled == false)
- {
- MessageBox.Show("请先停止服务!", "Server提示");
- e.Cancel = true;
- }
- }
- private void Form1_Load(object sender, EventArgs e)
- {
- // 在没有启动服务器之前,不允许停止服务以及发送信息
- button2.Enabled = false;
- button3.Enabled = false;
- }
- }
using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using System.Net; using System.Net.Sockets; using System.Threading; using System.IO; namespace ChartTestServer { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private NetworkStream networkStream; private StreamReader streamReader; private StreamWriter streamWriter; private Socket socketForClient; private TcpListener tcpListener; private Thread serverThread; // 启动服务线程 private Thread recvThread;// 接收信息线程 private void button1_Click(object sender, EventArgs e) { serverThread = new Thread(new ThreadStart(Listen)); serverThread.Start(); } //[STAThread] private void Listen() { try { Int32 port = Int32.Parse(txtPort.Text); IPAddress ipAddress = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0]; tcpListener = new TcpListener(ipAddress, port); // 开始侦听 tcpListener.Start(); listBox1.Items.Add("服务已经启动!"); button1.Enabled = false; button2.Enabled = true; // 返回可以用以处理连接的Socket实例 socketForClient = tcpListener.AcceptSocket(); // 如果返回值是"true",则产生的套节字已经接受来自远方的连接请求 if (socketForClient.Connected) { button3.Enabled = true; listBox1.Items.Add("客户端成功连接上服务器!"); // 创建networkStream对象通过网络套节字来接受和发送数据 networkStream = new NetworkStream(socketForClient); // 从当前数据流中读取一行字符,返回值是字符串 streamReader = new StreamReader(networkStream); streamWriter = new StreamWriter(networkStream); recvThread = new Thread(new ThreadStart(RecvData)); recvThread.Start(); } } catch (Exception exc) { MessageBox.Show(exc.Message, "Server提示"); } } // 接收服务器发来的信息 private void RecvData() { string msg = streamReader.ReadLine(); // 如果不是接收到客户端发来的退出信息,则不断接收信息 while (!msg.Equals("exit")) { //statusChart1.Value = Convert.ToInt32(msg); listBox1.Items.Add("收到信息: " + msg); msg = streamReader.ReadLine(); } // 如果接收到客户的退出信息,则退出服务 button1.Enabled = true; button2.Enabled = false; button3.Enabled = false; listBox1.Items.Add("客户已经关闭"); listBox1.Items.Add("服务器关闭"); // 关闭资源 ReleaseResource(); } private void button3_Click(object sender, EventArgs e) { Thread sendThread = new Thread(new ThreadStart(SendData)); sendThread.Start(); } private void SendData() { if (txtMsg.Text != "") { listBox1.Items.Add("发送信息: " + txtMsg.Text); // 往当前的数据流中写入一行字符串 streamWriter.WriteLine(txtMsg.Text); // 刷新当前数据流中的数据 streamWriter.Flush(); txtMsg.Text = ""; // 清空 } else { MessageBox.Show("发送信息不能为空", "提示"); } } private void button2_Click(object sender, EventArgs e) { try { if (button3.Enabled == true) { // 停止服务后,允许 启动服务,但是不允许发送消息 button1.Enabled = true; button2.Enabled = false; button3.Enabled = false; string exitMsg = "exit"; // 要退出时,发送 exit 信息给客户端 streamWriter.WriteLine(exitMsg); // 刷新当前数据流中的数据 streamWriter.Flush(); listBox1.Items.Add("服务器关闭"); // 释放资源 recvThread.Abort(); ReleaseResource(); } else { // 停止服务后,允许 启动服务,但是不允许发送消息 button1.Enabled = true; button2.Enabled = false; button3.Enabled = false; listBox1.Items.Add("服务器关闭"); // 关闭TCP连接,关闭线程 tcpListener.Stop(); serverThread.Abort(); } } catch (Exception exc) { MessageBox.Show(exc.Message, "Server提示"); } } // 释放资源 private void ReleaseResource() { networkStream.Close(); streamReader.Close(); streamWriter.Close(); socketForClient.Shutdown(SocketShutdown.Both); socketForClient.Close(); tcpListener.Stop(); } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { // 在未停止 服务 前,不允许关闭窗体 if (button1.Enabled == false) { MessageBox.Show("请先停止服务!", "Server提示"); e.Cancel = true; } } private void Form1_Load(object sender, EventArgs e) { // 在没有启动服务器之前,不允许停止服务以及发送信息 button2.Enabled = false; button3.Enabled = false; } }
- using System;
- using System.Drawing;
- using System.Collections;
- using System.ComponentModel;
- using System.Windows.Forms;
- using System.Data;
- using System.Net;
- using System.Net.Sockets;
- using System.Threading;
- using System.IO;
- namespace ChartTest
- {
- public partial class Form1 : Form
- {
- public Form1()
- {
- InitializeComponent();
- }
- private NetworkStream networkStream;
- private StreamReader streamReader;
- private StreamWriter streamWriter;
- private TcpClient myclient;
- private Thread recvThread; // 接收信息线程
- private Thread sendThread;// 发送信息线程
- private Thread serverThread;// 服务线程
- private Thread st;
- private void button1_Click(object sender, EventArgs e)
- {
- serverThread = new Thread(new ThreadStart(Connection));
- serverThread.Start();
- }
- private void Connection()
- {
- /*
- try
- {
- IPAddress ipAddress = IPAddress.Parse(txtIP.Text);
- Int32 port = Int32.Parse(txtPort.Text);
- IPEndPoint ipe = new IPEndPoint(ipAddress, port);
- myclient = new TcpClient();
- myclient.Connect(ipe);
- }
- catch
- {
- MessageBox.Show("没有连接到服务器!");
- return;
- }
- */
- try
- {
- IPAddress ipAddress = IPAddress.Parse(txtIP.Text);
- Int32 port = Int32.Parse(txtPort.Text);
- string hostName = Dns.GetHostEntry(ipAddress).HostName;
- myclient = new TcpClient(hostName, port);
- }
- catch
- {
- MessageBox.Show("没有连接到服务器!");
- return;
- }
- listBox1.Items.Add("客户端成功连接上服务器!");
- button1.Enabled = false; // 连接上了,不让按“连接”按钮
- button2.Enabled = true;
- button3.Enabled = true;
- networkStream = myclient.GetStream();
- streamReader = new StreamReader(networkStream);
- streamWriter = new StreamWriter(networkStream);
- // 创建接收信息线程,并启动
- recvThread = new Thread(new ThreadStart(RecvData));
- recvThread.Start();
- }
- // 接收数据
- private void RecvData()
- {
- string s = streamReader.ReadLine();
- // 如果没接到服务器退出的消息,则继续接收信息
- while (s!=null&&!s.Equals("exit"))
- {
- listBox1.Items.Add("收到信息:" + s);
- s = streamReader.ReadLine();
- }
- // 收到服务器退出的消息,释放资源
- listBox1.Items.Add("服务器关闭");
- listBox1.Items.Add("客户端关闭");
- button1.Enabled = true;
- button2.Enabled = false;
- button3.Enabled = false;
- // streamReader.Close();
- // streamWriter.Close();
- // networkStream.Close();
- // myclient.Close();
- ReleaseResouce();
- }
- private void button2_Click(object sender, EventArgs e)
- {
- button1.Enabled = true; // 按了停止之后,“连接”按钮可以用,“发送”不能用
- button2.Enabled = false;
- button3.Enabled = false;
- string exitMsg = "exit"; // 要退出时,发送 exit 信息给服务器
- streamWriter.WriteLine(exitMsg);
- //刷新当前数据流中的数据
- streamWriter.Flush();
- listBox1.Items.Add("客户端关闭");
- ReleaseResouce();
- }
- private void button3_Click(object sender, EventArgs e)
- {
- // 启动发送线程
- sendThread = new Thread(new ThreadStart(SendData));
- sendThread.Start();
- }
- // 发送数据
- private void SendData()
- {
- // 发送信息不允许为空
- if (txtMsg.Text == "")
- {
- MessageBox.Show("发送的信息不能为空!");
- txtMsg.Focus();
- return;
- }
- try
- {
- //往当前的数据流中写入一行字符串
- streamWriter.WriteLine(txtMsg.Text);
- //刷新当前数据流中的数据
- streamWriter.Flush();
- listBox1.Items.Add("发送信息:" + txtMsg.Text);
- txtMsg.Text = ""; // 清空
- }
- catch (Exception exc)
- {
- MessageBox.Show(exc.Message, "ClientClient提示");
- }
- }
- private void Form1_Load(object sender, EventArgs e)
- {
- // 在未连接服务器前,不能发送信息和停止
- button2.Enabled = false;
- button3.Enabled = false;
- }
- // 释放资源
- private void ReleaseResouce()
- {
- networkStream.Close();
- streamReader.Close();
- streamWriter.Close();
- if (sendThread!=null&&sendThread.IsAlive)
- {
- sendThread.Abort();
- }
- if (recvThread.IsAlive)
- {
- recvThread.Abort();
- }
- if (serverThread.IsAlive)
- {
- serverThread.Abort();
- }
- myclient.Close();
- }
- private void Form1_FormClosing(object sender, FormClosingEventArgs e)
- {
- // 如果是在连接中,则不允许关闭窗口
- if (button1.Enabled == false)
- {
- MessageBox.Show("请先停止连接!","ClientClient提示");
- e.Cancel = true;
- }
- }
- private void button4_Click(object sender, EventArgs e)
- {
- // 启动发送线程
- st = new Thread(new ThreadStart(SeData));
- st.Start();
- }
- // 发送数据
- private void SeData()
- {
- Random r = new Random();
- for (int i = 0; i < 10000; i++)
- {
- Thread.Sleep(400);
- try
- {
- //往当前的数据流中写入一行字符串
- streamWriter.WriteLine(r.Next(80).ToString());
- //刷新当前数据流中的数据
- streamWriter.Flush();
- listBox1.Items.Add("发送信息:" + r.Next(80).ToString());
- }
- catch (Exception exc)
- {
- MessageBox.Show(exc.Message, "ClientClient提示");
- }
- }
- }
- private void button5_Click(object sender, EventArgs e)
- {
- st.Abort();
- }
- }
- }
- using System;
- using System.Drawing;
- using System.Collections;
- using System.ComponentModel;
- using System.Windows.Forms;
- using System.Data;
- using System.Net;
- using System.Net.Sockets;
- using System.Threading;
- using System.IO;
- namespace ChartTest
- {
- public partial class Form1 : Form
- {
- public Form1()
- {
- InitializeComponent();
- }
- private NetworkStream networkStream;
- private StreamReader streamReader;
- private StreamWriter streamWriter;
- private TcpClient myclient;
- private Thread recvThread; // 接收信息线程
- private Thread sendThread; // 发送信息线程
- private Thread serverThread;// 服务线程
- private Thread st;
- private void button1_Click(object sender, EventArgs e)
- {
- serverThread = new Thread(new ThreadStart(Connection));
-  
以上是关于Tcpclient简单聊天程序的主要内容,如果未能解决你的问题,请参考以下文章
Socket入门笔记 用TcpClient实现一个简易聊天室
Delphi中的TcpServer和TcpClient以及UdpSocket的问题