博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Socket通信简介
阅读量:5045 次
发布时间:2019-06-12

本文共 12594 字,大约阅读时间需要 41 分钟。

  第一次做CS的程序,关于socket的,通过各种资料的搜索,其实我觉得说白了主要就分为:

  1、套结的关键字。

  2、服务器和客户机的远程通信。

  3、消息的处理。

  服务器原理

1 //把ip地址转换为实例 2                 IPAddress ipa = IPAddress.Parse("127.0.0.1"); 3                 //监听端口8001 4                 TcpListener mylsn = new TcpListener(ipa, 8001); 5                 //开启监听 6                 mylsn.Start(); 7                 //输出监听成功的信息 8                 Console.WriteLine("在8001启动服务,等待连接"); 9                 //等待处理接入连接请求10                 while (true)11                 {12                     Socket mysock = mylsn.AcceptSocket();13                     Console.WriteLine("有连接,连接来自" + mysock.RemoteEndPoint);14                     work w = new work();15                     w.mysock = mysock;16                     w.mylsn = mylsn;17                     Thread t = new Thread(new ThreadStart(w.main));18                     t.Start();19                 }
View Code

  class类:

1 class work 2     { 3         public Socket mysock; 4         public TcpListener mylsn; 5         public void main() 6         { 7             //接收客户端消息 8             byte[] data = new byte[100]; 9             mysock.Receive(data);10             string rt = System.Text.UTF8Encoding.UTF8.GetString(data);11             Console.WriteLine(rt);12             //给客户端发消息13             mysock.Send(UTF8Encoding.UTF8.GetBytes("server callback"));14             //释放资源15             mysock.Close();16             mylsn.Stop();17         }18     }
View Code

  客户机原理:

1 int port = 8001; 2                 string host = "127.0.0.1"; 3                 //创建终结点EndPoint 4                 IPAddress ip = IPAddress.Parse(host); 5                 IPEndPoint ipe = new IPEndPoint(ip, port);   //把ip和端口转化为IPEndPoint的实例 6  7                 //创建Socket并连接到服务器 8                 Socket c = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);   //  创建Socket 9                 Console.WriteLine("Connecting...");10                 c.Connect(ipe); //连接到服务器11 12                 //向服务器发送信息13                 string sendStr = "Hello,this is a socket test";14                 byte[] bs = Encoding.ASCII.GetBytes(sendStr);   //把字符串编码为字节15 16                 Console.WriteLine("Send message");17                 c.Send(bs, bs.Length, 0); //发送信息18 19                 //接受从服务器返回的信息20                 string recvStr = "";21                 byte[] recvBytes = new byte[1024];22                 int bytes;23                 bytes = c.Receive(recvBytes, recvBytes.Length, 0);    //从服务器端接受返回信息24                 recvStr += Encoding.ASCII.GetString(recvBytes, 0, bytes);25                 Console.WriteLine("client get message:{0}", recvStr);    //回显服务器的返回信息26 27                 Console.ReadLine();28                 //一定记着用完Socket后要关闭29                 c.Close();
View Code

  命名空间:System.Net和System.Net.Sockets(通信) System.IO(消息字节处理)

  到这里,我想通信已经完整的建立了,但是有些小朋友肯定会问,这只是一个简单的客户机和主机的联系,那么,一个主机,N个客户机,又是怎么回事呢,

  服务器原理:

1     private TcpListener myListener; 2     myListener = new TcpListener(localAddress, port); 3     myListener.Start(); 4  5     service.AddItem(string.Format("开始在{0}:{1}监听客户端连接", localAddress, port)); 6     //创建一个线程监听客户端连接请求 7     ThreadStart ts = new ThreadStart(ListenClientConnect);//委托 8     Thread myThread = new Thread(ts); 9     myThread.Start();10     11     12      private void ListenClientConnect()13         {14             while (true)15             {16                 TcpClient newClient = null;17                 try18                 {19                     //等待用户进入20                     newClient = myListener.AcceptTcpClient();21                 }22                 catch23                 {24                     //当单击“停止监听”或者退出此窗体时AcceptTcpClient()会产生异常25                     //因此可以利用此异常退出循环26                     break;27                 }28                 //每接受一个客户端连接,就创建一个对应的线程循环接收客户端发来的信息29                 ParameterizedThreadStart pts = new ParameterizedThreadStart(ReceiveData);//委托30                 Thread threadReceive = new Thread(pts);31                 User user = new User(newClient);32                 threadReceive.Start(user);33                 userList.Add(user);34                 service.AddItem(string.Format("{0}进入", newClient.Client.RemoteEndPoint));35                 service.AddItem(string.Format("当前连接用户数:{0}", userList.Count));36             }37         }38     39      private void ReceiveData(object obj)40         {41             User user = (User)obj;42             TcpClient client = user.client;43             //是否正常退出接收线程44             bool normalExit = false;45             //用于控制是否退出循环46             bool exitWhile = false;47             while (exitWhile == false)48             {49                 //当前要传送的数据50                 string receiveString = null;51                 try52                 {53                     receiveString = user.sr.ReadLine();54                 }55                 catch (Exception ex)56                 {57                     //该客户底层套接字不存在时会出现异常58                     service.AddItem("接收数据失败,原因:" + ex.Message);59                 }60                 //TcpClient 对象将套接字进行了封装,如果TcpClient对象关闭了,61                 //但是底层套接字未关闭,并不产生异常,但是读取的结果为 null62                 if (receiveString == null)63                 {64                     if (normalExit == false)65                     {66                         //如果停止了监听,Connected 为 false67                         if (client.Connected == true)68                         {69                             service.AddItem(string.Format("与{0}失去联系,已停止接收该用户信息",70                                 client.Client.RemoteEndPoint));71                         }72                     }73                     //退出循环74                     break;75                 }76                 service.AddItem(string.Format("来自{0}:{1}", user.userName, receiveString));77                 string[] splitString = receiveString.Split(',');78                 string command = splitString[0].ToLower();79                 //获取当前传送的数据80                 switch (command)81                 {82                     default:83                         service.SendToAll(userList, "要发送的数据");84                         break;85                 }86             }87             userList.Remove(user);88             client.Close();89             service.AddItem(string.Format("有一个退出,剩余连接用户数:{0}", userList.Count));90         }
View Code

  Service类:

class Service    {        private ListBox listbox;        private delegate void AddItemDelegate(string str);        private AddItemDelegate addItemDelegate;        public Service(ListBox listbox)        {            this.listbox = listbox;            addItemDelegate = new AddItemDelegate(AddItem);        }        ///         /// 在listbox中追加信息        ///         /// 要追加的信息        public void AddItem(string str)        {            if (listbox.InvokeRequired)                listbox.Invoke(addItemDelegate, str);            else            {                listbox.Items.Add(str);                listbox.SelectedIndex = listbox.Items.Count - 1;                listbox.ClearSelected();            }        }        ///         /// 向某个客户端发送信息        ///         /// 指定客户        /// 信息        public void SendToOne(User user, string str)        {            try            {                user.sw.WriteLine(str);                user.sw.Flush();                AddItem(string.Format("向{0}发送{1}", user.userName, str));            }            catch (Exception ex)            {                AddItem(string.Format("向{0}发送消息失败,原因:{1}", user.userName, ex.Message));            }        }        ///         /// 向所有客户端发送信息        ///         /// 客户列表        /// 信息        public void SendToAll(List
userList, string str) { for (int i = 0; i < userList.Count; i++) { SendToOne(userList[i], str); } } }
View Code

  客户机组(list)类:

1  ///  2     /// 客户机 3     ///  4     class User 5     { 6         public TcpClient client { get; set; } 7         public StreamReader sr { get; private set; } 8         public StreamWriter sw { get; private set; } 9         public string userName { get; set; }10         public User(TcpClient client)11         {12             this.client = client;13             this.userName = "";14             NetworkStream netStream = client.GetStream();15             sr = new StreamReader(netStream, Encoding.UTF8);16             sw = new StreamWriter(netStream, Encoding.UTF8);17         }18     }
View Code

  其实,现在呢,就是把整个客户机放到一个list里面,而listbox只是为了单纯的显示消息而已

  客户机原理:

1         private TcpClient client = null; 2         private StreamWriter sw; 3         private StreamReader sr; 4         private Service service; 5         //是否正常退出接收线程 6         private bool normalExit = false; 7          8         ///  9         /// 连接服务器10         /// 11         private void GetService()12         {13             try14             {15                 client = new TcpClient();16                 //服务器IP17                 client.Connect(IPAddress.Parse(ConfigurationManager.AppSettings["IP"]), int.Parse(ConfigurationManager.AppSettings["Port"]));18                 //获取网络流19                 NetworkStream netStream = client.GetStream();20                 sr = new StreamReader(netStream, System.Text.Encoding.UTF8);21                 sw = new StreamWriter(netStream, System.Text.Encoding.UTF8);22                 //信息基本提示23                 service = new Service(listBox1, sw);24                 //给服务器消息25                 service.SendToServer("success");26                 //数据处理(服务器消息)27                 Thread threadReceive = new Thread(new ThreadStart(ReceiveData));28                 threadReceive.Start();29             }30             catch (Exception ex)31             {32                 MessageBox.Show("与服务器连接失败,原因:" + ex.Message, "提示",33                     MessageBoxButtons.OK, MessageBoxIcon.Information);34                 return;35             }36 37         }38         /// 39         /// 接受服务器端的消息40         /// 41         private void ReceiveData()42         {43             bool exitWhile = false;44             while (exitWhile == false)45             {46                 string receiveString = null;47                 try48                 {49                     receiveString = sr.ReadLine();50                 }51                 catch52                 {53                     service.AddItemToListBox("接收数据失败");54                 }55                 if (receiveString == null)56                 {57                     if (normalExit == false)58                     {59                         MessageBox.Show("与服务器失去联系!");60                     }61                     //结束线程62                     break;63                 }64                 service.AddItemToListBox("收到:" + receiveString);65                 string[] splitString = receiveString.Split(',');66                 string command = splitString[0].ToLower();67                 switch (command)68                 {69                     default:70                         GetControl(command);//这里的GetControl是一个处理值的方法,71                         this.Invalidate();72                         break;73                 }74             }75             Application.Exit();76         }
View Code

  客户机Service类:

1     class Service 2     { 3         ListBox listbox; 4         StreamWriter sw; 5         public Service(ListBox listbox, StreamWriter sw) 6         { 7             this.listbox = listbox; 8             this.sw = sw; 9         }10         /// 向服务器发送数据11         public void SendToServer(string str)12         {13             try14             {15                 sw.WriteLine(str);16                 sw.Flush();17             }18             catch19             {20                 AddItemToListBox("发送数据失败");21             }22         }23         delegate void ListBoxDelegate(string str);24         /// 在listbox中追加信息<25         /// 要追加的信息26         public void AddItemToListBox(string str)27         {28             try29             {30                 if (listbox.InvokeRequired)31                 {32                     ListBoxDelegate d = AddItemToListBox;33                     listbox.Invoke(d, str);34                 }35                 else36                 {37                     listbox.Items.Add(str);38                     listbox.SelectedIndex = listbox.Items.Count - 1;39                     listbox.ClearSelected();40                 }41             }42             catch43             {44 45             }46         }47     }
View Code

  这就是一个完整的socket了,第一次做,肯定很多没有想到的地方,希望大神及时提出宝贵意见。

转载于:https://www.cnblogs.com/JeffController/p/4398495.html

你可能感兴趣的文章
LinearLayout
查看>>
学习python:day1
查看>>
css3动画属性
查看>>
第九次团队作业-测试报告与用户使用手册
查看>>
Equal Sides Of An Array
查看>>
CentOS笔记-用户和用户组管理
查看>>
Mongodb 基本命令
查看>>
Qt中QTableView中加入Check列实现
查看>>
“富豪相亲大会”究竟迷失了什么?
查看>>
控制文件的备份与恢复
查看>>
返回代码hdu 2054 A==B?
查看>>
Flink独立集群1
查看>>
iOS 8 地图
查看>>
20165235 第八周课下补做
查看>>
[leetcode] 1. Two Sum
查看>>
iOS 日常工作之常用宏定义大全
查看>>
PHP的SQL注入技术实现以及预防措施
查看>>
MVC Razor
查看>>
软件目录结构规范
查看>>
Windbg调试Sql Server 进程
查看>>