码迷,mamicode.com
首页 > 其他好文 > 详细

04Socket网络编程的服务器写法

时间:2016-02-28 22:55:32      阅读:262      评论:0      收藏:0      [点我收藏+]

标签:

  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.Net;
  8 using System.Net.Sockets;
  9 using System.Text;
 10 using System.Threading;
 11 using System.Threading.Tasks;
 12 using System.Windows.Forms;
 13 
 14 namespace _02ChatServer
 15 {
 16     public partial class ChatServer : Form
 17     {
 18         public ChatServer()
 19         {
 20             Control.CheckForIllegalCrossThreadCalls = false;
 21             InitializeComponent();
 22         }
 23         Socket skListen = null;//为了服务器能够控制监听的停止,把监听的socket声明在外面.
 24         Dictionary<string, Socket> dicClient = new Dictionary<string, Socket>();
 25         private void button1_Click(object sender, EventArgs e)
 26         {
 27             if (skListen == null)
 28             {
 29                 //开启一个Socket进行监听通讯的端口
 30                 skListen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 31             }
 32             //绑定IP和端口号
 33             skListen.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9999));
 34             //设置监听的队列
 35             skListen.Listen(10);
 36             lblState.ForeColor = Color.Green;
 37             lblState.Font = new Font("黑体", 30);
 38             lblState.Text = "监听中..";
 39 
 40             
 41 
 42             Thread thread = new Thread(new ThreadStart(() => {
 43                 //不断接收用户的连接请求.
 44                 while (true)
 45                 {
 46                     //准备客户端的连接;
 47                     Socket skConnetion = skListen.Accept();//这句话会阻塞主线程,所以要把他放在一个单独的线程中.
 48                     //当客户端连接的时候将IP端口号和Socket帮定到一个集合中
 49                     dicClient.Add(skConnetion.RemoteEndPoint.ToString(), skConnetion);
 50                     listboxClients.Items.Add( skConnetion.RemoteEndPoint.ToString());
 51                     txtLog.AppendText(skConnetion.RemoteEndPoint.ToString() + "已经连接上了.."+Environment.NewLine);
 52                     //当一个用户连接上的时候如果不发送消息的时候就会阻塞当前线程所有要再创建一个线程来接收用户的消息.
 53                     //使用线程池来创建一个线程执行客户端接收用户消息,下面的lamada表达式通过传入客户端的连接socket来实现函数的内部访问客户端连接的socket,当传入的不是lanmeda表达式的时候可以使用这种方法传入客户端socket.
 54                     ThreadPool.QueueUserWorkItem(new WaitCallback(obj=>{
 55                         Socket skReceive = skConnetion as Socket;
 56 
 57                         byte[] buffer=new byte[1024 * 1024 * 4];
 58                        //因为客户端发送的消息不是只发一个,要不断的重复接收用户的信息发送
 59                         while (true)
 60                         {
 61                            
 62                            int count= skReceive.Receive(buffer);
 63                            if (count == 0) 
 64                            {
 65                                //用户退出了
 66                                txtLog.AppendText("客户端"+skReceive.RemoteEndPoint.ToString()+"已退出");
 67                                dicClient.Remove(skReceive.RemoteEndPoint.ToString());
 68                                listboxClients.Items.Remove(skReceive.RemoteEndPoint.ToString());
 69                                break;
 70                            }
 71                            string msg = Encoding.UTF8.GetString(buffer,0,count);
 72                            txtLog.AppendText("客户端"+skConnetion.RemoteEndPoint.ToString()+"发来消息:"+msg+Environment.NewLine);//易外耳门特
 73                         }
 74                     
 75                     }),skConnetion);
 76                 }
 77                 
 78             }));
 79             thread.IsBackground = true;
 80             thread.Start();
 81             
 82 
 83         }
 84 
 85         private void button3_Click(object sender, EventArgs e)
 86         {
 87             //判断是否选中了要通讯的ip端口
 88             if (listboxClients.SelectedItem != null)
 89             {
 90                 //根据用户的选中的端口,找到通讯的scoket
 91                 Socket sk = dicClient[listboxClients.SelectedItem.ToString()];
 92                 if (sk != null)
 93                 {
 94                     //把用户输入的消息转化成字节数组
 95                     byte[] buffer = Encoding.UTF8.GetBytes(txtSendMsg.Text.Trim());
 96                     byte[] sendBuffer=new byte[buffer.Length+1];
 97 
 98                     Buffer.BlockCopy(buffer, 0, sendBuffer, 1, buffer.Length);
 99                     //向客户端发送了消息
100                     sk.Send(sendBuffer);
101                     //写入日志
102                     txtLog.AppendText("服务器向[" + listboxClients.SelectedItem.ToString() + "]发送了:" + txtSendMsg.Text + Environment.NewLine);
103                 }
104             }
105             else
106             {
107                 MessageBox.Show("请选中要发送消息的客户端");
108             }
109         }
110 
111         private void button4_Click(object sender, EventArgs e)
112         {
113             if (listboxClients.SelectedItem != null)
114             {
115                 //1.根据选中的客户端端口ip选择通讯的socket
116                Socket skClient=  dicClient[listboxClients.SelectedItem.ToString()];
117                skClient.Send(new byte[] { 2 });//发送一个标记2来提示客户端发送的是一个闪屏
118 
119             }
120             else
121             {
122                 MessageBox.Show("请选择要发送的客户端");
123             }
124         }
125     }
126 }

 

04Socket网络编程的服务器写法

标签:

原文地址:http://www.cnblogs.com/clcloveHuahua/p/5225641.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!