完整版的Socket服务器端

上次的Socket服务器端只是开胃菜,这次我们把上次的代码进行完善和追加。

窗体如下

我根据读到的资料,对代码进行了重写

并对源码进行了大量的注释,希望大家能够读懂

 public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        //代理委托
        delegate void FlushSocket();

        //所有代理Socket的集合
        List<Socket> AgentSocketList = new List<Socket>();
        private void btnOpen_Click(object sender, EventArgs e)
        {
            //创建一个Socket对象
            Socket severSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //绑定端口和IP
            IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(txtIP.Text), int.Parse(txtPort.Text));
            severSocket.Bind(endPoint);
            //开始监听
            severSocket.Listen(10);

            //用别的线程来连接客户端
            ThreadPool.QueueUserWorkItem(new WaitCallback(CallBackSocket), severSocket);

        }

        //回调函数
        public void CallBackSocket(object obj)
        {
            //将参数obj强转成Socket类型
            Socket severSocket = (Socket)obj;
            //开始连接
            //主线程会在这里一直阻塞,直到连接到一个客户端
            //返回值是一个代理通信Socket对象

            //可能连接多个客户端,需要循环
            while (true)
            {
                Socket socket = severSocket.Accept();
                //往集合中添加代理Socket
                AgentSocketList.Add(socket);

                //解决跨线程访问控件问题
                if (this.txtLog.InvokeRequired)
                {
                    //FlushSocket fs = new FlushSocket(CallBackSocket);
                    txtLog.Invoke(new FlushSocket(() =>
                    {
                        FlushMsg(socket);
                    }));
                }
                else
                {
                    FlushMsg(socket);
                }

            }
        }

        //显示连接接收情况
        public void FlushMsg(Socket socket)
        {
            txtLog.Text = "已成功连接:" + socket.RemoteEndPoint + "\r\n" + this.txtLog.Text;
            //接收数据
            ThreadPool.QueueUserWorkItem(new WaitCallback(RecMsgFromClient), socket);

        }

        //接收数据
        public void RecMsgFromClient(object obj)
        {
            Socket socket = (Socket)obj;
            //1M的缓存区
            byte[] recByte = new byte[1024 * 1024];
            while (true)
            {
                //将接收到的数据,存到缓存区
                //因为Receive方法会阻塞线程,所以也需要用另一个线程来等待
                int count = socket.Receive(recByte, 0, recByte.Length, SocketFlags.None);

                //对方退出了
                if (count <= 0)
                {
                    if (this.txtLog.InvokeRequired)
                    {
                        txtLog.Invoke(new FlushSocket(() =>
                        {
                            txtLog.Text = string.Format("来自客户端{0}的消息;对方退出了\r\n{1}", socket.RemoteEndPoint, txtLog.Text);
                        }));
                    }
                    else
                    {
                        //给接收文本框赋值
                        txtLog.Text = string.Format("来自客户端{0}的消息;对方退出了\r\n{1}", socket.RemoteEndPoint, txtLog.Text);
                    }
                    //关闭代理Socket
                    socket.Shutdown(SocketShutdown.Both);
                    socket.Close();
                    AgentSocketList.Remove(socket);
                    return;
                }

                //将缓存区中的数据转成字符串
                string str = Encoding.Default.GetString(recByte, 0, count);

                if (this.txtLog.InvokeRequired)
                {
                    txtLog.Invoke(new FlushSocket(() =>
                    {
                        txtLog.Text = string.Format("来自客户端{0}的内容;{1}\r\n{2}", socket.RemoteEndPoint, str, txtLog.Text);
                    }));
                }
                else
                {
                    //给接收文本框赋值
                    txtLog.Text = string.Format("来自客户端{0}的内容;{1}\r\n{2}", socket.RemoteEndPoint, str, txtLog.Text);
                }

            }
        }

        //向客户端发送消息
        private void btnSend_Click(object sender, EventArgs e)
        {
            //遍历每一个代理Socket
            foreach (var socket in AgentSocketList)
            {
                //如果保持连接,就传输数据
                if (socket.Connected)
                {
                    byte[] myBuffer = Encoding.Default.GetBytes(txtSend.Text);
                    socket.Send(myBuffer,0,myBuffer.Length,SocketFlags.None);
                }
            }
        }

    }

下面是显示效果

右边的是客户端,大家可以先不用在意,后面我会写客户端的,这里是用的别人的来检验服务器端。

我使用了“123”来进行发送和接收,都没问题,暂没有发现bug

时间: 2024-10-05 08:16:59

完整版的Socket服务器端的相关文章

【电子书下载】《Android应用程序开发与典型案例》完整版!!

图书简介: <android应用程序开发与典型案例>共23章,内容包含两大部分.第一部分是android程序设计基础,在介绍android环境搭建以及android系统基本控件和组件后,详细介绍了android系统应用编程中典型的技术,比如,android中的图形图像.多媒体编程.gps定位与地图编程等:第二部分是android程序ui设计,从手机软件的交互设计谈起,介绍了android用户界面设计原则和方法.android用户界面设计哲学等,并给出了具体建议. <android应用程序

MySQL5.6 Replication主从复制(读写分离) 配置完整版

MySQL5.6主从复制(读写分离)教程 1.MySQL5.6开始主从复制有两种方式: 基于日志(binlog): 基于GTID(全局事务标示符). 需要注意的是:GTID方式不支持临时表!所以如果你的业务系统要用到临时表的话就不要考虑这种方式了,至少目前最新版本MySQL5.6.12的GTID复制还是不支持临时表的. 所以本教程主要是告诉大家如何通过日志(binlog)方式做主从复制! 2.MySQL官方提供的MySQL Replication教程: http://dev.mysql.com/

多人在线扑克游戏源码带服务端完整版

多人在线扑克游戏源码带服务端完整版,本项目源码是一套网络版的扑克牌项目源码,带服务器端源码,服务器端也是用java做的,打开游戏以后需要配置IP服务器端的IP和端口,服务端默认监听9999端口,客户端ip填写10.0.2.2,端口信息不用管直接点连接就可以连接到电脑上的服务端.项目源码注释比较丰富,可以研究一下里面的算法之类的.搭建这个服务端环境废了我半天劲,不知道是不是我运行的方法不对,打开前两个游戏客户端没有问题,打开第三个就开始直接强制退出.游戏没玩成所以没有截那部分的图.<ignore_

网易新闻应用源码完整版客户端+服务端源码

这个源码是从安卓教程网android分享过来的,看到这个项目比较不错,就转了.网易新闻应用源码完整版客户端+服务端源码,仿网易新闻,android端+服务器端1,为了加快访问速度,服务器端数据是写死了的,数据太多的就复制粘贴了,不是数据库查询的2,新闻图片下载代码注释掉了(网速给力的可以放开注释),显示的是默认图片 3.运行时记得改android端Constantvalues类里面的IP地址4,  UI结合使用的挺不错的等.<ignore_js_op>   <ignore_js_op&g

Linux学习总结(1)——Linux命令大全完整版

Linux命令大全完整版 目    录I 1. linux系统管理命令1 adduser1 chfn(change finger information)1 chsh(change shell)1 date2 exit3 finger4 free5 fwhois5 gitps(gnu interactive tools process status)5 groupdel(group delete)6 groupmod(group modify)6 halt7 id7 kill8 last8 la

office2016 软件全集 官方下载免费完整版(含破解文件)不含垃圾软件 win10完美激活

office2016官方下载免费完整版是新一代办公软件,office2016官方下载免费完整版已经分享到下面,office2016官方下载免费完整版包括了Word.Excel.PowerPoint.OneNote.Outlook.Skype.Project.Visio以及Publisher等组件和服务.下面分享:office2016软件的下载.安装及激活. 本文来自互联网,按原教程安装结果中招了,因含有垃圾软件,所以决定改写,以免你懂的... 注册文件下载中含有垃圾软件,请按下面的步骤操作会跳过

Hadoop实战视频教程完整版 完整的Hadoop大数据视频教程

分享一套迪伦老师的完整的Hadoop实战视频教程,教程从学习Hadoop需要的数据库.Java和Linux基础讲起,非常适合零基础的学员,课程最后结合了实战项目演练,理论结合实战,深入浅出,绝对是当前最为完整.实战的Hadoop教程. <Hadoop大数据零基础高端实战培训系列配文本挖掘项目(七大亮点.十大目标)> 课程讲师:迪伦 课程分类:大数据 适合人群:初级 课时数量:230课时 用到技术:部署Hadoop集群 涉及项目:京东商城.百度.阿里巴巴 咨询QQ:1337192913(小公子)

rip路由协议 细节分析及实例配置【完整版】

rip路由协议 细节分析及实例配置[完整版] RIP呢,这是一个比较重要的知识点,所以它的知识覆盖面很广泛:但是呢,我将会对碰到的问题进行一些分析解刨(主要是为了帮助自己理清思维):也希望能够从中发现自己不足的问题,也希望能够找到一些比较冷僻的问题,这样子才会有意思多了.   先上图,这个就是我准备做实验的基本用图了.现在已经按照图上标注的IP将所有基本配置设置好了. 在这个实验中,大多数都是基于ripv1,只有在需要比较的时候才会把版本改成ripv2,然后判断完之后再切换为ripv1: 第一步

信号处理必读的文章(-)—傅里叶分析之掐死教程(完整版)_转载至知乎

傅里叶分析之掐死教程(完整版)更新于2014.06.06 http://zhuanlan.zhihu.com/p/19763358 作 者:韩 昊 知 乎:Heinrich 微 博:@花生油工人 知乎专栏:与时间无关的故事 谨以此文献给大连海事大学的吴楠老师,柳晓鸣老师,王新年老师以及张晶泊老师. 转载的同学请保留上面这句话,谢谢.如果还能保留文章来源就更感激不尽了. ——更新于2014.6.6,想直接看更新的同学可以直接跳到第四章———— 我保证这篇文章和你以前看过的所有文章都不同,这是12年