Tcpclient简单聊天程序
来源:互联网 发布:淘宝天猫店招尺寸 编辑:程序博客网 时间:2024/05/16 11:35
以前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 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();
- }
- }
- }
关于线程访问控件问题,为了偷懒,我直接屏蔽了,在Program.cs的Main()函数中加入:
- System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls =false;
例子源码:http://download.csdn.net/detail/wangqiuyun/4502341
- Tcpclient简单聊天程序
- Tcpclient简单聊天程序
- 简单的聊天程序
- 简单聊天程序分析
- Java简单聊天程序
- HiChat简单聊天程序
- 简单聊天程序
- JAVA简单聊天程序
- C#简单聊天程序
- unity3d简单聊天程序
- socket 简单聊天程序
- WinForm中单个窗体实现P2P聊天程序(Socket,TcpListener,TcpClient,Thread,)
- 简单tcpclient服务器
- 简单的单机聊天程序
- UDP实现简单聊天程序
- 一个最简单聊天程序
- 简单的聊天小程序
- 简单的局域网聊天程序
- 在shell中启动后台执行程序,然后退出shell会引发 IOError [Errno 5] Input/output error
- 传统文件系统与NoSQL分布式存储的块存储技术对比(2)
- Netflow的配置方法
- opengl insights:4 webgl for opengl developers
- HTML5 web通信(跨文档通信/通道通信)简介
- Tcpclient简单聊天程序
- GEP中的轮盘赌选择程序(MATLAB)
- Flex采集摄像头照片----增加裁剪功能
- flex 事件机制-基于Actionscript 3.0
- 基因表达式编程---通过人工智能建立的数学模型
- VI reference
- cannot enable both sham-link state-change interface traps
- git邮件通知,非git原版的post-receive 改进了的
- Android获取屏幕大小为什么会自动减去状态栏高度