关于c# cs架构下socket
一、服务器端:
1、指定IP地址和端口 开启监听
IPAddress ip = IPAddress.Parse(ServerIP);
//配置监听IP地址和端口
tcpListener = new TcpListener(ip, ServerPort);
//启动监听
tcpListener.Start();
2、接收到客户端请求,并编写处理函数
Socket tempSocket = tcpListener.AcceptSocket();//接受挂起的连接请求
clientSocket = tempSocket;
byte[] buffer=new Byte[1024];
clientSocket.Receive(buffer, SocketFlags.None);//读取接收到的数据保存到buffer中
string tempReceive = System.Text.Encoding.UTF8.GetString(buffer);//转换接收到的字节缓存buffer为字符串
tempReceive=tempReceive.Replace("%7C", "|");//替换UTF中字符%7C为|
这样就得到客户端发送过来的请求“字符串”
服务器端源代码如下:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Net; using System.Net.Sockets; using System.Threading; namespace socketServer { public partial class Form1 : Form { #region 成员 private string ServerIP; private int ServerPort; //服务器监听状态 public bool ServerStatus = false; /// <summary> /// 用于TCP监听 /// </summary> private TcpListener tcpListener; /// <summary> /// 与客户端连接的套接字接口 socket /// </summary> private Socket clientSocket; /// <summary> /// 开启服务的线程 /// </summary> private Thread processor; /// <summary> /// 用于处理客户事件的线程 /// </summary> private Thread clientThread; /// <summary> /// 用于保存接收到的客户端发送内容 /// </summary> private string ReceiveContent=""; /// <summary> /// 用于开一条线程异步处理修改窗体控件 文本框信息 /// </summary> private Thread demoThread = null; #endregion public Form1() { InitializeComponent(); } #region 使用委托方法用其他线程修改窗体控件 delegate void SetTextCallback(string text); private void SetText(string text) { if (this.txtcontent.InvokeRequired) {//当一个控件的InvokeRequired属性值为真时,说明有一个创建它以外的线程想访问它 SetTextCallback d = new SetTextCallback(SetText); this.Invoke(d, new object[] { text }); } else { this.txtcontent.Text = text; } } private void ThreadProcSafe() { this.SetText(ReceiveContent); } #endregion #region 封装处理客户端传送数据的方法 public void ProcessorClient() { Socket client = clientSocket;//得到接收的挂起请求soket bool keepalive = true;//获取的状态,当有内容可读时为true;当没有内容或者读完时为false while(keepalive) { byte[] buffer = null; Thread.Sleep(50); bool tag = false; try { buffer=new Byte[1024]; int count = client.Receive(buffer, SocketFlags.None);//读取接收到的数据保存到buffer中 if (count > 0) tag = true;//接收到的数据大于0 } catch { keepalive = false;//跳出接收数据循环条件 if (client.Connected) client.Disconnect(true);//关闭套接字连接并允许重用套接字 client.Close();//关闭socket } if (!tag) { keepalive = false;//跳出接收数据循环条件 if (client.Connected) client.Disconnect(true);//关闭套接字连接并允许重用套接字 client.Close();//关闭socket } //把接收到的信息显示到txtcontent文本框上 string tempReceive = ""; try { //转换接收到的字节缓存buffer为字符串 tempReceive = System.Text.Encoding.UTF8.GetString(buffer); tempReceive=tempReceive.Replace("%7C", "|");//替换UTF中字符%7C为| string[] message = tempReceive.Split('|'); if (tag) { if (ReceiveContent == "") { ReceiveContent = message[0]; } else { ReceiveContent += "\r\n" + message[0]; } } //另开一个线程来刷新txtcontent文本框 this.demoThread = new Thread(new ThreadStart(this.ThreadProcSafe)); this.demoThread.Start(); //this.SetText(ReceiveContent);//亦可以直接使用 } catch { } } } #endregion #region 封装启动服务监听的方法 /// <summary> /// 封装启动服务监听的方法 /// </summary> public void startListening() { try { IPAddress ip = IPAddress.Parse(ServerIP); //配置监听IP地址和端口 tcpListener = new TcpListener(ip, ServerPort); //启动监听 tcpListener.Start(); while (true) { Thread.Sleep(50); try { Socket tempSocket = tcpListener.AcceptSocket();//接受挂起的连接请求 clientSocket = tempSocket; //开启处理客户端传递信息的新线程 clientThread = new Thread(new ThreadStart(ProcessorClient)); clientThread.Start(); clientThread.IsBackground = true; } catch(Exception e) { } } } catch(Exception ex) { MessageBox.Show(ex.Message, "信息提示"); this.ServerStatus = false; processor.Abort(); } } #endregion #region 开启服务 /// <summary> /// 开启服务 /// </summary> public void StartServer() { try { if (ServerStatus == true) { MessageBox.Show("监听服务器已经开启!", "信息提示"); } else { //开一个监听的线程启动监听 processor = new Thread(new ThreadStart(startListening)); processor.Start(); processor.IsBackground = true; } this.ServerStatus = true; } catch(Exception ex) { MessageBox.Show(ex.Message, "开启监听服务器错误!"); } } #endregion #region 停止服务 /// <summary> /// 停止服务 /// </summary> public void stopServer() { try { if (ServerStatus == true) { //关闭监听 tcpListener.Stop(); Thread.Sleep(1000); //终止线程 processor.Abort(); } else { MessageBox.Show("监听服务已经停止!", "信息提示"); } this.ServerStatus = false; } catch(Exception ex) { MessageBox.Show(ex.Message, "停止监听服务器错误!"); } } #endregion #region 按钮操作 /// <summary> /// 开始监听按钮 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { try { ServerIP = txtIP.Text.Trim(); ServerPort = int.Parse(txtport.Text.Trim()); StartServer(); button1.Enabled = false; button2.Enabled = true; this.label2.Text = "监听中......"; } catch { MessageBox.Show("开启监听服务器失败!", "信息提示"); this.label2.Text = "已停止"; } } /// <summary> /// 停止监听按钮 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button2_Click(object sender, EventArgs e) { stopServer(); button1.Enabled = true; button2.Enabled = false; this.label2.Text = "已停止"; } private void button3_Click(object sender, EventArgs e) { ReceiveContent = ""; this.txtcontent.Text = ""; } #endregion } }
二、客户端
1、指定服务器端IP和端口号
ServerIP = this.txtIP.Text.Trim();
IPAddress ip = IPAddress.Parse(ServerIP);
ServerPort = Convert.ToInt32(this.txtPort.Text.Trim());
ServerInfo = new IPEndPoint(ip, ServerPort);
2、定义socket并连接服务器
//定义一个IPV4,TCP模式的Socket
ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//建立客户端与服务器端的连接
ClientSocket.Connect(ServerInfo);
3、发送请求(字节形式发送)
private Byte[] sendMsg = Encoding.UTF8.GetBytes(DateTime.Now.ToShortTimeString() + "[" + username + "]登录聊天室|test");
ClientSocket.Send(sendMsg);
客户端源代码如下:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Net; using System.Net.Sockets; namespace socketTest { public partial class Form1 : Form { private string ServerIP; private int ServerPort; private IPEndPoint ServerInfo;//服务器IP和端口 private Socket ClientSocket; //套接字接口 private Byte[] sendMsg;//用于把发送内容字符串转换成字节 private string username; public Form1() { InitializeComponent(); this.button2.ForeColor = Color.Blue; } private void button2_Click(object sender, EventArgs e) { username = this.txtuser.Text.Trim(); if (username== "") { MessageBox.Show("用户名不能为空!","信息提示"); return; } try { if (this.button2.Text == "连接服务器") {//连接服务器 //创建服务器的IP和端口(IPEndPoint) ServerIP = this.txtIP.Text.Trim(); IPAddress ip = IPAddress.Parse(ServerIP); ServerPort = Convert.ToInt32(this.txtPort.Text.Trim()); ServerInfo = new IPEndPoint(ip, ServerPort); //定义一个IPV4,TCP模式的Socket ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //建立客户端与服务器端的连接 ClientSocket.Connect(ServerInfo); //发送登录聊天室消息 sendMsg = Encoding.UTF8.GetBytes(DateTime.Now.ToShortTimeString() + "[" + username + "]登录聊天室|test"); ClientSocket.Send(sendMsg); this.label2.Text = "已连接"; this.button2.Text = "断开服务器"; this.button2.ForeColor = Color.Red; } else {//断开服务器 //发送离开聊天室消息 sendMsg = Encoding.UTF8.GetBytes(DateTime.Now.ToShortTimeString() + "[" + username + "]离开聊天室|test"); ClientSocket.Send(sendMsg); if (ClientSocket.Connected) ClientSocket.Disconnect(true); ClientSocket.Close(); this.label2.Text = "已断开"; this.button2.Text = "连接服务器"; this.button2.ForeColor = Color.Blue; } } catch(Exception ex) { MessageBox.Show(ex.Message, "连接或断开服务器错误"); this.label2.Text = "未连接"; } } private void button1_Click(object sender, EventArgs e) { if (ClientSocket != null && ClientSocket.Connected) { if (this.txtContent.Text.Trim() == "") { MessageBox.Show("发送内容不能为空!", "信息提示"); return; } sendMsg = Encoding.UTF8.GetBytes("[" + username + "]说:" + this.txtContent.Text.Trim() + "|test"); ClientSocket.Send(sendMsg); this.txtContent.Text = ""; //MessageBox.Show("内容已发送成功!","信息提示"); } else { MessageBox.Show("未连接服务器,不能发送信息!","温馨提示"); } } } }
运行效果如图: