C#菜鸟做这个东东竟然花了快三天的时间了 真是菜菜菜下面是我用C#写的一个简单的TCP通信 主要的功能有
1 多个客户端与服务器间的数据交流
2可以实现群发的功能
3客户端与服务端可以进行文件的传输
主要用到的知识 TCP里的 socket 、 、 、 多线程Thread 、 、 、
下面的是界面
下面分别是服务端和客户端的代码如若借用 请标明出处~~~服务端代码
[csharp]view plaincopyprint?using System;using System.Col lections.Generic;using System.ComponentModel ;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.Net.Sockets;using System.Net;//IP IPAddress, IPEndPoint 端口等using System.Threading;using System.IO;namespace_11111
{publ ic partial class frm_server :Form
{publ icfrm_server()
{
Initial izeComponent();
TextBox.CheckForIl legalCrossThreadCal ls=false;
}
Thread threadWatch=nul l ;// 负责监听客户端连接请求的线程
Socket socketWatch=nul l ;
Dictionary<string,Socket>dict=new Dictionary<string,Socket>();
Dictionary<string,Thread>dictThread=new Dictionary<string,Thread>();private void btnBeginListen_Cl ick(object sender,EventArgs e)
{
//创建负责监听的套接字 注意其中的参数socketWatch = new Socket(AddressFami ly.InterNetwork, SocketType.Stream,ProtocolType.Tcp);
//获得文本框中的IP对象
IPAddress address=IPAddress.Parse(txtIp.Text.Trim());
//创建包含ip和端口号的网络节点对象
IPEndPoint endPoint=new IPEndPoint(address, int.Parse(txtPort.Text.Trim()));t ry
{
//将负责监听的套接字绑定到唯一的ip和端口上socketWatch.Bind(endPoint);
}catch(SocketException se)
{
MessageBox.Show("异常 "+se.Message);return;
}
//设置监听队列的长度socketWatch.Li sten(10);
//创建负责监听的线程threadWatch=new Thread(WatchConnecting);threadWatch.IsBackground=true;threadWatch.Start();
ShowMsg("服务器启动监听成功 ");
//}
}
///<summary>
///监听客户端请求的方法
///</summary>voidWatchConnecting()
{while(true)//持续不断的监听客户端的连接请求
{
//开始监听客户端连接请求 Accept方法会阻断当前的线程
Socket sokConnection=socketWatch.Accept();//一旦监听到一个客户端的请求就返回一个与该客户端通信的套接字
//想列表控件中添加客户端的IP信息lbOnline.Items.Add(sokConnection.RemoteEndPoint.ToString());
//将与客户端连接的套接字对象添加到集合中dict.Add(sokConnection.RemoteEndPoint.ToString(), sokConnection);
ShowMsg("客户端连接成功 ");
Thread thr=new Thread(RecMsg);thr.IsBackground=true;thr.Start(sokConnection);dictThread.Add(sokConnection.RemoteEndPoint.ToString(), thr); //将新建的线程 添加到线程的集合中去。
}
}void RecMsg(object sokConnectionparn)
{
Socket sokCl ient=sokConnectionparn as Socket;while(true)
{
//定义一个2M的缓存区byte[]arrMsgRec=new byte[1024*1024*2];
//将接受到的数据存入到输入arrMsgRec中int length=-1 ;t ry
{length=sokCl ient.Receive(arrMsgRec);//接收数据 并返回数据的长度
}catch(SocketException se)
{
ShowMsg("异常 "+se.Message);
//从通信套接字 集合中删除被中断连接的通信套接字dict.Remove(sokClient.RemoteEndPoint.ToString());
//从通信线程集合中删除被中断连接的通信线程对象dictThread.Remove(sokClient.RemoteEndPoint.ToString());
//从列表中移除被中断的连接IP lbOnline.Items.Remove(sokClient.RemoteEndPoint.ToString());break;
}catch(Exception e)
{
ShowMsg("异常 "+e.Message);
//从通信套接字 集合中删除被中断连接的通信套接字dict.Remove(sokClient.RemoteEndPoint.ToString());
//从通信线程集合中删除被中断连接的通信线程对象dictThread.Remove(sokClient.RemoteEndPoint.ToString());
//从列表中移除被中断的连接IP lbOnline.Items.Remove(sokClient.RemoteEndPoint.ToString());break;
}if(arrMsgRec[0]==0)//表示接收到的是数据
{string strMsg= System.Text.Encoding.UTF8.GetString(arrMsgRec,1, length-1);//将接受到的字节数据转化成字符串
ShowMsg(strMsg);
}if(arrMsgRec[0]==1)//表示接收到的是文件
{
SaveFi leDialog sfd=new SaveFi leDialog();if(sfd.ShowDialog(this)==System.Windows.Forms.DialogResult.OK)
{//在上边的 sfd.ShowDialog 的括号里边一定要加上this否则就不会弹出 另存为 的对话框 而弹出的是本类的其他窗口 这个一定要注意 【解释 加了 this 的sfd.ShowDialog(this) “另存为”窗口的指针才能被SaveFi leDialog 的对象调用 若不加thisSaveFi leDialog的对象调用的是本类的其他窗口了 当然不弹出“另存为”窗口。】stringfi leSavePath=sfd.Fi leName;//获得文件保存的路径
//创建文件流 然后根据路径创建文件using(Fi leStream fs=new Fi leStream(fileSavePath,Fi leMode.Create))
{fs.Write(arrMsgRec, 1, length- 1);
ShowMsg("文件保存成功 "+fi leSavePath);
}
}
}
}
}void ShowMsg(string str)
{txtMsg.AppendText(str+"\r\n");
}
//发送消息
private void btnSend_Cl ick(object sender,EventArgs e)
{string strMsg="服务器"+"\r\n"+" -->"+txtMsgSend.Text.Trim()+"\r\n";byte[] arrMsg= System.Text.Encoding.UTF8.GetBytes(strMsg); //将要发送的字符串转换成Utf-8字节数组byte[]arrSendMsg=new byte[arrMsg.Length+1];arrSendMsg[0]=0;//表示发送的是消息数据
Buffer.BlockCopy(arrMsg,0,arrSendMsg, 1,arrMsg.Length);string strKey="";strKey=lbOnline.Text.Trim();if(string.IsNullOrEmpty(strKey))//判断是不是选择了发送的对象
{
MessageBox.Show("请选择你要发送的好友 ");
}else
{dict[strKey].Send(arrSendMsg);//解决了 sokConnection是局部变量不能再本函数中引用的问题
ShowMsg(strMsg);txtMsgSend.Clear();
}
}
///<summary>
///群发消息
///</summary>
///<param name="sender"></param>
///<param name="e">消息</param>private void btnSendToAl l_Cl ick(object sender,EventArgs e)
{string strMsg="服务器"+"\r\n"+" -->"+txtMsgSend.Text.Trim()+"\r\n";byte[] arrMsg= System.Text.Encoding.UTF8.GetBytes(strMsg); //将要发送的字符串转换成Utf-8字节数组using System;using System.Col lections.Generic;using System.ComponentModel ;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.Net.Sockets;using System.Net; //IP IPAddress, IPEndPoint 端口等using System.Threading;
using System.IO;namespace_11111
{publ ic partial class frm_server :Form
{publ icfrm_server()
{
Initial izeComponent();
TextBox.CheckForIl legalCrossThreadCal ls=false;
}
Thread threadWatch=nul l ;// 负责监听客户端连接请求的线程
Socket socketWatch=nul l ;
Dictionary<string,Socket>dict=new Dictionary<string,Socket>();
Dictionary<string,Thread>dictThread=new Dictionary<string,Thread>();private void btnBeginListen_Cl ick(object sender,EventArgs e)
{
//创建负责监听的套接字 注意其中的参数socketWatch=new Socket(AddressFami ly.InterNetwork, SocketType.Stream,ProtocolType.Tcp);
//获得文本框中的IP对象
IPAddress address=IPAddress.Parse(txtIp.Text.Trim());
//创建包含ip和端口号的网络节点对象
IPEndPoint endPoint = new IPEndPoint(address,int.Parse(txtPort.Text.Trim()));t ry
{
//将负责监听的套接字绑定到唯一的ip和端口上socketWatch.Bind(endPoint);
}catch(SocketException se)
{
MessageBox.Show("异常 "+se.Message);return;
}
//设置监听队列的长度socketWatch.Li sten(10);
//创建负责监听的线程threadWatch=new Thread(WatchConnecting);threadWatch.IsBackground=true;threadWatch.Start();
ShowMsg("服务器启动监听成功 ");
//}
}
///<summary>
///监听客户端请求的方法
///</summary>voidWatchConnecting()
{while(true) //持续不断的监听客户端的连接请求
{
//开始监听客户端连接请求 Accept方法会阻断当前的线程
Socket sokConnection=socketWatch.Accept(); //一旦监听到一个客户端的请求 就返回一个与该客户端通信的套接字
//想列表控件中添加客户端的IP信息lbOnline.Items.Add(sokConnection.RemoteEndPoint.ToString());
//将与客户端连接的套接字对象添加到集合中dict.Add(sokConnection.RemoteEndPoint.ToString(), sokConnection);
ShowMsg("客户端连接成功 ");
Thread thr=new Thread(RecMsg);thr.IsBackground=true;thr.Start(sokConnection);dictThread.Add(sokConnection.RemoteEndPoint.ToString(), thr); //将新建的线程添加到线程的集合中去。
}
}void RecMsg(object sokConnectionparn)
{
Socket sokCl ient=sokConnectionparn as Socket;while(true)
{
//定义一个2M的缓存区byte[]arrMsgRec=new byte[1024*1024*2];
//将接受到的数据存入到输入 arrMsgRec中int length=-1 ;t ry
{length=sokCl ient.Receive(arrMsgRec);//接收数据 并返回数据的长度
}catch(SocketException se)
{
ShowMsg("异常 "+se.Message);
//从通信套接字 集合中删除被中断连接的通信套接字dict.Remove(sokClient.RemoteEndPoint.ToString());
//从通信线程集合中删除被中断连接的通信线程对象dictThread.Remove(sokClient.RemoteEndPoint.ToString());
//从列表中移除被中断的连接IP lbOnline.Items.Remove(sokClient.RemoteEndPoint.ToString());break;
}catch(Exception e)
{
ShowMsg("异常 "+e.Message);
//从通信套接字 集合中删除被中断连接的通信套接字dict.Remove(sokClient.RemoteEndPoint.ToString());
//从通信线程集合中删除被中断连接的通信线程对象dictThread.Remove(sokClient.RemoteEndPoint.ToString());
//从列表中移除被中断的连接IP lbOnline.Items.Remove(sokClient.RemoteEndPoint.ToString());break;
}if(arrMsgRec[0]==0) //表示接收到的是数据
{string strMsg =System.Text.Encoding.UTF8.GetString(arrMsgRec,1, length-1);//将接受到的字节数据转化成字符串
ShowMsg(strMsg);
}if(arrMsgRec[0]==1)//表示接收到的是文件
{
SaveFi leDialog sfd=new SaveFi leDialog();if (sfd.ShowDialog(this) ==System.Windows.Forms.DialogResult.OK)
{//在上边的sfd.ShowDialog 的括号里边一定要加上this否则就不会弹出 另存为 的对话框而弹出的是本类的其他窗口 这个一定要注意 【解释加了 this的sfd.ShowDialog(this) “另存为”窗口的指针才能被SaveFi leDialog的对象调用若不加thisSaveFi leDialog的对象调用的是本类的其他窗口了当然不弹出“另存为”窗口。】string fi leSavePath=sfd.Fi leName;//获得文件保存的路径
//创建文件流 然后根据路径创建文件using (Fi leStream fs = new Fi leStream(fi leSavePath,Fi leMode.Create))
{
puaex怎么样?puaex是一家去年成立的国人商家,本站也分享过几次,他家主要销售香港商宽的套餐,给的全部为G口带宽,而且是不限流量的,目前有WTT和HKBN两种线路的方面,虽然商家的价格比较贵,但是每次补一些货,就会被抢空,之前一直都是断货的状态,目前商家进行了补货,有需要这种类型机器的朋友可以入手。点击进入:puaex商家官方网站Puaex香港vds套餐:全部为KVM虚拟架构,G口的带宽,可...
最近看到群里的不少网友在搭建大数据内容网站,内容量有百万篇幅,包括图片可能有超过50GB,如果一台服务器有需要多个站点的话,那肯定默认的服务器50GB存储空间是不够用的。如果单独在购买数据盘会成本提高不少。这里我们看到腾讯云促销活动中有2款带大数据盘的套餐还是比较实惠的,一台是400GB数据盘,一台是800GB数据盘,适合他们的大数据网站。 直达链接 - 腾讯云 大数据盘套餐服务器这里我们看到当前...
快快CDN主营业务为海外服务器无须备案,高防CDN,防劫持CDN,香港服务器,美国服务器,加速CDN,是一家综合性的主机服务商。美国高防服务器,1800DDOS防御,单机1800G DDOS防御,大陆直链 cn2线路,线路友好。快快CDN全球安全防护平台是一款集 DDOS 清洗、CC 指纹识别、WAF 防护为一体的外加全球加速的超强安全加速网络,为您的各类型业务保驾护航加速前进!价格都非常给力,需...