要求:
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;

服务端代码如下:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using System.Windows.Forms;
  10.  
  11. using System.Net;
  12. using System.Net.Sockets;
  13. using System.Threading;
  14. using System.IO;
  15.  
  16. namespace Socket_ServerAndClient
  17. {
  18. public partial class Form1 : Form
  19. {
  20. public Form1()
  21. {
  22. InitializeComponent();
  23. TextBox.CheckForIllegalCrossThreadCalls = false;
  24. }
  25.  
  26. Thread threadWatch = null;
  27. Socket socketWatch = null;
  28.  
  29. /// <summary>
  30. /// 创建服务
  31. /// </summary>
  32. /// <param name="sender"></param>
  33. /// <param name="e"></param>
  34. private void button1_Click(object sender, EventArgs e)
  35. {
  36. socketWatch = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
  37. IPAddress address = IPAddress.Parse(txtIP.Text.Trim());
  38. IPEndPoint endpoint = new IPEndPoint(address,int.Parse(txtPort.Text.Trim()));
  39. socketWatch.Bind(endpoint);
  40. socketWatch.Listen(10);
  41. threadWatch = new Thread(WatchConnection);
  42. threadWatch.IsBackground = true;
  43. threadWatch.Start();
  44. ShowMsg("服务器监听成功......");
  45. }
  46.  
  47. //Socket sokConnection = null;
  48. Dictionary<string, Socket> dict = new Dictionary<string, Socket>();
  49. Dictionary<string, Thread> dictThread = new Dictionary<string, Thread>();
  50.  
  51. /// <summary>
  52. /// 监听客户端的请求方法
  53. /// </summary>
  54. /// <param name="obj"></param>
  55. private void WatchConnection(object obj)
  56. {
  57. while (true)
  58. {
  59. // 负责通信的套接字
  60. Socket sokConnection = socketWatch.Accept();
  61. lb_Online.Items.Add(sokConnection.RemoteEndPoint.ToString());
  62. dict.Add(sokConnection.RemoteEndPoint.ToString(),sokConnection);
  63.  
  64. //创建通信线程
  65. ParameterizedThreadStart pts = new ParameterizedThreadStart(RecMsg);// 委托
  66. Thread thr = new Thread(pts);
  67. thr.IsBackground = true;
  68. thr.Start(sokConnection);
  69. dictThread.Add(sokConnection.RemoteEndPoint.ToString(),thr);
  70.  
  71. ShowMsg("客户端连接成功......"+sokConnection.RemoteEndPoint.ToString());
  72. }
  73. }
  74.  
  75. /// <summary>
  76. /// 服务端负责监听客户端发送消息的方法
  77. /// </summary>
  78. void RecMsg(object socketClient)
  79. {
  80. Socket socketClients = socketClient as Socket;
  81. while (true)
  82. {
  83. byte[] arrMsgRec = new byte[1024 * 1024 * 2];
  84.  
  85. int length = -1;
  86. try
  87. {
  88. length = socketClients.Receive(arrMsgRec);
  89. }
  90. catch (SocketException ex)
  91. {
  92. ShowMsg("异常:" + ex.Message);
  93. // 从 通信套接字 集合中删除被中断连接的套接字对象
  94. dict.Remove(socketClients.RemoteEndPoint.ToString());
  95. // 从 通信线程 集合中删除被中断连接的套接字对象
  96. dictThread.Remove(socketClients.RemoteEndPoint.ToString());
  97. // 从 列表 中移除 IP&Port
  98. lb_Online.Items.Remove(socketClients.RemoteEndPoint.ToString());
  99. break;
  100. }
  101. catch (Exception ex)
  102. {
  103. ShowMsg("异常:" + ex.Message);
  104. break;
  105. }
  106. // 判断第一个发送过来的数据如果是1,则代表发送过来的是文本数据
  107. if (arrMsgRec[0] == 0)
  108. {
  109. string strMsgRec = System.Text.Encoding.UTF8.GetString(arrMsgRec, 1, length-1);
  110. ShowMsg(strMsgRec);
  111. }
  112. // 若是1则发送过来的是文件数据(文档,图片,视频等。。。)
  113. else if(arrMsgRec[0] == 1)
  114. {
  115. // 保存文件选择框对象
  116. SaveFileDialog sfd = new SaveFileDialog();
  117. // 选择文件路径
  118. if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
  119. {
  120. // 获得保存文件的路径
  121. string fileSavePath = sfd.FileName;
  122. // 创建文件流,然后让文件流根据路径创建一个文件
  123. using (FileStream fs = new FileStream(fileSavePath, FileMode.Create))
  124. {
  125. fs.Write(arrMsgRec, 1, length - 1);
  126. ShowMsg("文件保存成功:"+fileSavePath);
  127. }
  128. }
  129. }
  130. }
  131. }
  132.  
  133. private void ShowMsg(string p)
  134. {
  135. txtMsg.AppendText(p+"\r\n");
  136. }
  137.  
  138. /// <summary>
  139. /// 发送消息
  140. /// </summary>
  141. /// <param name="sender"></param>
  142. /// <param name="e"></param>
  143. private void Send_Click_Click(object sender, EventArgs e)
  144. {
  145. if (string.IsNullOrEmpty(lb_Online.Text))
  146. {
  147. MessageBox.Show("请选择发送的好友!!!");
  148. }
  149. else
  150. {
  151. string strMsg = tb_Msg_Send.Text.Trim();
  152. byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg);
  153. string strClientKey = lb_Online.Text;
  154. try
  155. {
  156. dict[strClientKey].Send(arrMsg);
  157. ShowMsg("发送了数据出去:"+strMsg);
  158. }
  159. catch (SocketException ex)
  160. {
  161. ShowMsg("发送时异常:" + ex.Message);
  162. }
  163. catch(Exception ex)
  164. {
  165. ShowMsg("发送时异常:" + ex.Message);
  166. }
  167. // sokConnection.Send(arrMsg);
  168. ShowMsg("发送了数据出去:"+strMsg);
  169. }
  170. }
  171.  
  172. /// <summary>
  173. /// 群发消息
  174. /// </summary>
  175. /// <param name="sender"></param>
  176. /// <param name="e"></param>
  177. private void SendToAll_Click(object sender, EventArgs e)
  178. {
  179. string strMsg = txtMsg.Text.Trim();
  180. byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg);
  181. foreach (Socket item in dict.Values)
  182. {
  183. item.Send(arrMsg);
  184. }
  185. ShowMsg("群发完毕!!!:)");
  186. }
  187. }
  188. }

  

客户端代码如下:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using System.Windows.Forms;
  10. using System.Net;
  11. using System.Net.Sockets;
  12. using System.Threading;
  13. using System.IO;
  14.  
  15. namespace Socket_Client
  16. {
  17. public partial class Form1 : Form
  18. {
  19. public Form1()
  20. {
  21. InitializeComponent();
  22. TextBox.CheckForIllegalCrossThreadCalls = false;
  23. }
  24.  
  25. Thread threadRec = null;
  26. Socket socketClient = null;
  27.  
  28. private void btn_Connect_Click(object sender, EventArgs e)
  29. {
  30. IPAddress address = IPAddress.Parse(tb_IP.Text.Trim());
  31. IPEndPoint endport = new IPEndPoint(address,int.Parse(tb_Port.Text.Trim()));
  32. socketClient = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
  33. socketClient.Connect(endport);
  34.  
  35. threadRec = new Thread(RecMsg);
  36. threadRec.IsBackground = true;
  37. threadRec.Start();
  38. }
  39.  
  40. void RecMsg()
  41. {
  42. while (true)
  43. {
  44. byte[] arrMsgRec = new byte[1024*1024*2];
  45. int length = socketClient.Receive(arrMsgRec);
  46. string strMsgRec = System.Text.Encoding.UTF8.GetString(arrMsgRec,0,length);
  47. ShowMsg(strMsgRec);
  48. }
  49. }
  50.  
  51. private void ShowMsg(string msg)
  52. {
  53. tb_Msg.AppendText(msg+"\r\n");
  54. }
  55.  
  56. private void btnSendMsg_Click(object sender, EventArgs e)
  57. {
  58. string strMsg = txtMsgSend.Text.Trim();
  59. byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg);
  60. byte[] arrMsgSend = new byte[arrMsg.Length];
  61. // 添加标识位,0代表发送的是文字
  62. arrMsgSend[0] = 0;
  63. Buffer.BlockCopy(arrMsg, 0, arrMsgSend, 1, arrMsg.Length);
  64. socketClient.Send(arrMsg);
  65. ShowMsg("I say:"+strMsg);
  66. }
  67.  
  68. /// <summary>
  69. /// 选择文件
  70. /// </summary>
  71. /// <param name="sender"></param>
  72. /// <param name="e"></param>
  73. private void btChoseFile_Click(object sender, EventArgs e)
  74. {
  75. OpenFileDialog ofd = new OpenFileDialog();
  76. if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
  77. {
  78. txtFilePath.Text = ofd.FileName;
  79. }
  80. }
  81.  
  82. /// <summary>
  83. /// 发送文件
  84. /// </summary>
  85. /// <param name="sender"></param>
  86. /// <param name="e"></param>
  87. private void btSendFile_Click(object sender, EventArgs e)
  88. {
  89. using (FileStream fs = new FileStream())
  90. {
  91. byte[] arrFile = new byte[1024*1024*2];
  92. int length = fs.Read(arrFile, 0, arrFile.Length);
  93. byte[] arrFileSend = new byte[length+1];
  94. arrFileSend[0] = 1;// 代表文件数据
  95. // 将数组 arrFile 里的数据从第零个数据拷贝到 数组 arrFileSend 里面,从第1个开始,拷贝length个数据
  96. Buffer.BlockCopy(arrFile, 0, arrFileSend, 1, length);
  97. socketClient.Send(arrFileSend);
  98. }
  99. }
  100. }
  101. }

程序运行截图:

  

(C#:Socket)简单的服务端与客户端通信。的更多相关文章

  1. Netty 学习(二):服务端与客户端通信

    Netty 学习(二):服务端与客户端通信 作者: Grey 原文地址: 博客园:Netty 学习(二):服务端与客户端通信 CSDN:Netty 学习(二):服务端与客户端通信 说明 Netty 中 ...

  2. C#Winform窗体实现服务端和客户端通信例子(TCP/IP)

    Winform窗体实现服务端和客户端通信的例子,是参考这个地址 http://www.cnblogs.com/longwu/archive/2011/08/25/2153636.html 进行了一些异 ...

  3. C# 编写WCF简单的服务端与客户端

    http://www.wxzzz.com/1860.html Windows Communication Foundation(WCF)是由微软开发的一系列支持数据通信的应用程序框架,可以翻译为Win ...

  4. C# Socket服务端与客户端通信(包含大文件的断点传输)

    步骤: 一.服务端的建立 1.服务端的项目建立以及页面布局 2.各功能按键的事件代码 1)传输类型说明以及全局变量 2)Socket通信服务端具体步骤:   (1)建立一个Socket   (2)接收 ...

  5. socket创建UDP服务端和客户端

    UDP服务端代码示例: from socket import * #1.创建数据报套接字 sockfd = socket(AF_INET, SOCK_DGRAM) #2.绑定服务端地 sockfd.b ...

  6. socket创建TCP服务端和客户端

    看情况选择相对应的套接字*面向连接的传输--tcp协议--可靠的--流式套接字(SOCK_STREAM)*面向无连接的传输--udp协议--不可靠的--数据报套接字(SOCK_DGRAM) 在liun ...

  7. go --socket通讯(TCP服务端与客户端的实现)

    这篇文章主要使用Go语言实现一个简单的TCP服务器和客户端.服务器和客户端之间的协议是 ECHO, 这个RFC 862定义的一个简单协议.为什么说这个协议很简单呢, 这是因为服务器只需把收到的客户端的 ...

  8. C# Socket简单例子(服务器与客户端通信)

    这个例子只是简单实现了如何使用 Socket 类实现面向连接的通信. 注意:此例子的目的只是为了说明用套接字写程序的大概思路,而不是实际项目中的使用程序.在这个例子中,实际上还有很多问题没有解决,如消 ...

  9. java网络编程-单线程服务端与客户端通信

    该服务器一次只能处理一个客户端请求;p/** * 利用Socket进行简单服务端与客户端连接 * 这是服务端 */public class EchoServer { private ServerSoc ...

随机推荐

  1. Led控件

    在 WindowMobile 上的模拟LED 显示屏插件 一个简单Led控件 一个经典的控制Led的单片机程序 Led控件(2)——Led显示屏模拟

  2. angularjs ajax传参

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script sr ...

  3. IOS开发中摇一摇是怎么实现的

    三个方法,分别是开始摇一摇,结束摇一摇,取消摇一摇,我们可以在里面对应的进行事件处理,或者在ui上进行信息展示: 1.开始摇一摇:(在实际app中用需要处理的语句替换NSLog(@"开始摇一 ...

  4. 可用于Windows Server 2008 R2的Xbox One手柄、接收器驱动

    让客厅里的Gen8可以玩FC和PS1游戏,折腾了半天,终于将Xbox One手柄驱动弄好: http://www.drvsky.com/Microsoft/Xbox_One.htm http://ww ...

  5. 解决VirtualBox下安装虚拟机(Ubuntu)出错(不能为虚拟电脑Ubuntu打开一个新的任务)的有关问题

    [转]http://www.myexception.cn/program/1964906.html 解决VirtualBox下安装虚拟机(Ubuntu)出错(不能为虚拟电脑Ubuntu打开一个新的任务 ...

  6. OmniGraffle-新手指南

    OmniGraffle是一款不错的可视化软件,通过它你可以把你想要展现的数据简介.直观的展现在图.表上,这是我在数据可视化工具这篇随笔中说过的功能.但是当我真正用它时,我发现它可以做的事情还有很多. ...

  7. IM 融云 之 安装cocoapods 安装 SDK

    1. podfile 内容如下: platform :ios, '7.0' pod 'RongCloudIMKitWithVoip', '2.4.3' 现在最新是2.4.3 导入之后,就直接可以用了. ...

  8. 在ubtuntu中使用包管理器 linux-brew

    用惯了mac的程序员回到linux开发平台总觉得有点不适应,这是因为linux的界面没有mac那么精美,而且linux的包管理器没有mac上面的homebrew那么强大.mac程序员遇到库的依赖问题时 ...

  9. UITextField 之 手势收起键盘

    1. 注册手势 /** * 注册手势 */ -(void)gestureReg{ //放弃第一响应者 UITapGestureRecognizer * tap = [[UITapGestureReco ...

  10. 要重定向 IO 流,Process 对象必须将 UseShellExecute 属性设置为 False。

    Process  p1= new Process(); p1.StartInfo.UseShellExecute = false;