(C#:Socket)简单的服务端与客户端通信。
要求:
1.可以完成一对一的通信;
2.实现服务端对客户端一对多的选择发送;
3.可以实现服务端的群发功能;
4.可以实现客户端文件的发送;
要点:
服务器端:
第一步:用指定的端口号和服务器的ip建立一个EndPoint对像;
第二步:建立一个Socket对像;
第三步:用socket对像的Bind()方法绑定EndPoint;
第四步:用socket对像的Listen()方法开始监听;
第五步:接受到客户端的连接,用socket对像的Accept()方法创建新的socket对像用于和请求的客户端进行通信;
第六步:通信结束后一定记得关闭socket;
客户端:
第一步:用指定的端口号和服务器的ip建立一个EndPoint对像;
第二步:建立一个Socket对像;
第三步:用socket对像的Connect()方法以上面建立的EndPoint对像做为参数,向服务器发出连接请求;
第四步:如果连接成功,就用socket对像的Send()方法向服务器发送信息;
第五步:用socket对像的Receive()方法接受服务器发来的信息 ;
第六步:通信结束后一定记得关闭socket;
服务端代码如下:
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows.Forms;
- using System.Net;
- using System.Net.Sockets;
- using System.Threading;
- using System.IO;
- namespace Socket_ServerAndClient
- {
- public partial class Form1 : Form
- {
- public Form1()
- {
- InitializeComponent();
- TextBox.CheckForIllegalCrossThreadCalls = false;
- }
- Thread threadWatch = null;
- Socket socketWatch = null;
- /// <summary>
- /// 创建服务
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void button1_Click(object sender, EventArgs e)
- {
- socketWatch = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
- IPAddress address = IPAddress.Parse(txtIP.Text.Trim());
- IPEndPoint endpoint = new IPEndPoint(address,int.Parse(txtPort.Text.Trim()));
- socketWatch.Bind(endpoint);
- socketWatch.Listen(10);
- threadWatch = new Thread(WatchConnection);
- threadWatch.IsBackground = true;
- threadWatch.Start();
- ShowMsg("服务器监听成功......");
- }
- //Socket sokConnection = null;
- Dictionary<string, Socket> dict = new Dictionary<string, Socket>();
- Dictionary<string, Thread> dictThread = new Dictionary<string, Thread>();
- /// <summary>
- /// 监听客户端的请求方法
- /// </summary>
- /// <param name="obj"></param>
- private void WatchConnection(object obj)
- {
- while (true)
- {
- // 负责通信的套接字
- Socket sokConnection = socketWatch.Accept();
- lb_Online.Items.Add(sokConnection.RemoteEndPoint.ToString());
- dict.Add(sokConnection.RemoteEndPoint.ToString(),sokConnection);
- //创建通信线程
- ParameterizedThreadStart pts = new ParameterizedThreadStart(RecMsg);// 委托
- Thread thr = new Thread(pts);
- thr.IsBackground = true;
- thr.Start(sokConnection);
- dictThread.Add(sokConnection.RemoteEndPoint.ToString(),thr);
- ShowMsg("客户端连接成功......"+sokConnection.RemoteEndPoint.ToString());
- }
- }
- /// <summary>
- /// 服务端负责监听客户端发送消息的方法
- /// </summary>
- void RecMsg(object socketClient)
- {
- Socket socketClients = socketClient as Socket;
- while (true)
- {
- byte[] arrMsgRec = new byte[1024 * 1024 * 2];
- int length = -1;
- try
- {
- length = socketClients.Receive(arrMsgRec);
- }
- catch (SocketException ex)
- {
- ShowMsg("异常:" + ex.Message);
- // 从 通信套接字 集合中删除被中断连接的套接字对象
- dict.Remove(socketClients.RemoteEndPoint.ToString());
- // 从 通信线程 集合中删除被中断连接的套接字对象
- dictThread.Remove(socketClients.RemoteEndPoint.ToString());
- // 从 列表 中移除 IP&Port
- lb_Online.Items.Remove(socketClients.RemoteEndPoint.ToString());
- break;
- }
- catch (Exception ex)
- {
- ShowMsg("异常:" + ex.Message);
- break;
- }
- // 判断第一个发送过来的数据如果是1,则代表发送过来的是文本数据
- if (arrMsgRec[0] == 0)
- {
- string strMsgRec = System.Text.Encoding.UTF8.GetString(arrMsgRec, 1, length-1);
- ShowMsg(strMsgRec);
- }
- // 若是1则发送过来的是文件数据(文档,图片,视频等。。。)
- else if(arrMsgRec[0] == 1)
- {
- // 保存文件选择框对象
- SaveFileDialog sfd = new SaveFileDialog();
- // 选择文件路径
- if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
- {
- // 获得保存文件的路径
- string fileSavePath = sfd.FileName;
- // 创建文件流,然后让文件流根据路径创建一个文件
- using (FileStream fs = new FileStream(fileSavePath, FileMode.Create))
- {
- fs.Write(arrMsgRec, 1, length - 1);
- ShowMsg("文件保存成功:"+fileSavePath);
- }
- }
- }
- }
- }
- private void ShowMsg(string p)
- {
- txtMsg.AppendText(p+"\r\n");
- }
- /// <summary>
- /// 发送消息
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void Send_Click_Click(object sender, EventArgs e)
- {
- if (string.IsNullOrEmpty(lb_Online.Text))
- {
- MessageBox.Show("请选择发送的好友!!!");
- }
- else
- {
- string strMsg = tb_Msg_Send.Text.Trim();
- byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg);
- string strClientKey = lb_Online.Text;
- try
- {
- dict[strClientKey].Send(arrMsg);
- ShowMsg("发送了数据出去:"+strMsg);
- }
- catch (SocketException ex)
- {
- ShowMsg("发送时异常:" + ex.Message);
- }
- catch(Exception ex)
- {
- ShowMsg("发送时异常:" + ex.Message);
- }
- // sokConnection.Send(arrMsg);
- ShowMsg("发送了数据出去:"+strMsg);
- }
- }
- /// <summary>
- /// 群发消息
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void SendToAll_Click(object sender, EventArgs e)
- {
- string strMsg = txtMsg.Text.Trim();
- byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg);
- foreach (Socket item in dict.Values)
- {
- item.Send(arrMsg);
- }
- ShowMsg("群发完毕!!!:)");
- }
- }
- }
客户端代码如下:
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows.Forms;
- using System.Net;
- using System.Net.Sockets;
- using System.Threading;
- using System.IO;
- namespace Socket_Client
- {
- public partial class Form1 : Form
- {
- public Form1()
- {
- InitializeComponent();
- TextBox.CheckForIllegalCrossThreadCalls = false;
- }
- Thread threadRec = null;
- Socket socketClient = null;
- private void btn_Connect_Click(object sender, EventArgs e)
- {
- IPAddress address = IPAddress.Parse(tb_IP.Text.Trim());
- IPEndPoint endport = new IPEndPoint(address,int.Parse(tb_Port.Text.Trim()));
- socketClient = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
- socketClient.Connect(endport);
- threadRec = new Thread(RecMsg);
- threadRec.IsBackground = true;
- threadRec.Start();
- }
- void RecMsg()
- {
- while (true)
- {
- byte[] arrMsgRec = new byte[1024*1024*2];
- int length = socketClient.Receive(arrMsgRec);
- string strMsgRec = System.Text.Encoding.UTF8.GetString(arrMsgRec,0,length);
- ShowMsg(strMsgRec);
- }
- }
- private void ShowMsg(string msg)
- {
- tb_Msg.AppendText(msg+"\r\n");
- }
- private void btnSendMsg_Click(object sender, EventArgs e)
- {
- string strMsg = txtMsgSend.Text.Trim();
- byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg);
- byte[] arrMsgSend = new byte[arrMsg.Length];
- // 添加标识位,0代表发送的是文字
- arrMsgSend[0] = 0;
- Buffer.BlockCopy(arrMsg, 0, arrMsgSend, 1, arrMsg.Length);
- socketClient.Send(arrMsg);
- ShowMsg("I say:"+strMsg);
- }
- /// <summary>
- /// 选择文件
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void btChoseFile_Click(object sender, EventArgs e)
- {
- OpenFileDialog ofd = new OpenFileDialog();
- if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
- {
- txtFilePath.Text = ofd.FileName;
- }
- }
- /// <summary>
- /// 发送文件
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void btSendFile_Click(object sender, EventArgs e)
- {
- using (FileStream fs = new FileStream())
- {
- byte[] arrFile = new byte[1024*1024*2];
- int length = fs.Read(arrFile, 0, arrFile.Length);
- byte[] arrFileSend = new byte[length+1];
- arrFileSend[0] = 1;// 代表文件数据
- // 将数组 arrFile 里的数据从第零个数据拷贝到 数组 arrFileSend 里面,从第1个开始,拷贝length个数据
- Buffer.BlockCopy(arrFile, 0, arrFileSend, 1, length);
- socketClient.Send(arrFileSend);
- }
- }
- }
- }
程序运行截图:
(C#:Socket)简单的服务端与客户端通信。的更多相关文章
- Netty 学习(二):服务端与客户端通信
Netty 学习(二):服务端与客户端通信 作者: Grey 原文地址: 博客园:Netty 学习(二):服务端与客户端通信 CSDN:Netty 学习(二):服务端与客户端通信 说明 Netty 中 ...
- C#Winform窗体实现服务端和客户端通信例子(TCP/IP)
Winform窗体实现服务端和客户端通信的例子,是参考这个地址 http://www.cnblogs.com/longwu/archive/2011/08/25/2153636.html 进行了一些异 ...
- C# 编写WCF简单的服务端与客户端
http://www.wxzzz.com/1860.html Windows Communication Foundation(WCF)是由微软开发的一系列支持数据通信的应用程序框架,可以翻译为Win ...
- C# Socket服务端与客户端通信(包含大文件的断点传输)
步骤: 一.服务端的建立 1.服务端的项目建立以及页面布局 2.各功能按键的事件代码 1)传输类型说明以及全局变量 2)Socket通信服务端具体步骤: (1)建立一个Socket (2)接收 ...
- socket创建UDP服务端和客户端
UDP服务端代码示例: from socket import * #1.创建数据报套接字 sockfd = socket(AF_INET, SOCK_DGRAM) #2.绑定服务端地 sockfd.b ...
- socket创建TCP服务端和客户端
看情况选择相对应的套接字*面向连接的传输--tcp协议--可靠的--流式套接字(SOCK_STREAM)*面向无连接的传输--udp协议--不可靠的--数据报套接字(SOCK_DGRAM) 在liun ...
- go --socket通讯(TCP服务端与客户端的实现)
这篇文章主要使用Go语言实现一个简单的TCP服务器和客户端.服务器和客户端之间的协议是 ECHO, 这个RFC 862定义的一个简单协议.为什么说这个协议很简单呢, 这是因为服务器只需把收到的客户端的 ...
- C# Socket简单例子(服务器与客户端通信)
这个例子只是简单实现了如何使用 Socket 类实现面向连接的通信. 注意:此例子的目的只是为了说明用套接字写程序的大概思路,而不是实际项目中的使用程序.在这个例子中,实际上还有很多问题没有解决,如消 ...
- java网络编程-单线程服务端与客户端通信
该服务器一次只能处理一个客户端请求;p/** * 利用Socket进行简单服务端与客户端连接 * 这是服务端 */public class EchoServer { private ServerSoc ...
随机推荐
- Led控件
在 WindowMobile 上的模拟LED 显示屏插件 一个简单Led控件 一个经典的控制Led的单片机程序 Led控件(2)——Led显示屏模拟
- angularjs ajax传参
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script sr ...
- IOS开发中摇一摇是怎么实现的
三个方法,分别是开始摇一摇,结束摇一摇,取消摇一摇,我们可以在里面对应的进行事件处理,或者在ui上进行信息展示: 1.开始摇一摇:(在实际app中用需要处理的语句替换NSLog(@"开始摇一 ...
- 可用于Windows Server 2008 R2的Xbox One手柄、接收器驱动
让客厅里的Gen8可以玩FC和PS1游戏,折腾了半天,终于将Xbox One手柄驱动弄好: http://www.drvsky.com/Microsoft/Xbox_One.htm http://ww ...
- 解决VirtualBox下安装虚拟机(Ubuntu)出错(不能为虚拟电脑Ubuntu打开一个新的任务)的有关问题
[转]http://www.myexception.cn/program/1964906.html 解决VirtualBox下安装虚拟机(Ubuntu)出错(不能为虚拟电脑Ubuntu打开一个新的任务 ...
- OmniGraffle-新手指南
OmniGraffle是一款不错的可视化软件,通过它你可以把你想要展现的数据简介.直观的展现在图.表上,这是我在数据可视化工具这篇随笔中说过的功能.但是当我真正用它时,我发现它可以做的事情还有很多. ...
- IM 融云 之 安装cocoapods 安装 SDK
1. podfile 内容如下: platform :ios, '7.0' pod 'RongCloudIMKitWithVoip', '2.4.3' 现在最新是2.4.3 导入之后,就直接可以用了. ...
- 在ubtuntu中使用包管理器 linux-brew
用惯了mac的程序员回到linux开发平台总觉得有点不适应,这是因为linux的界面没有mac那么精美,而且linux的包管理器没有mac上面的homebrew那么强大.mac程序员遇到库的依赖问题时 ...
- UITextField 之 手势收起键盘
1. 注册手势 /** * 注册手势 */ -(void)gestureReg{ //放弃第一响应者 UITapGestureRecognizer * tap = [[UITapGestureReco ...
- 要重定向 IO 流,Process 对象必须将 UseShellExecute 属性设置为 False。
Process p1= new Process(); p1.StartInfo.UseShellExecute = false;