• NET中Socket编程的简单示例


    以下示例程序实现简单的socket通信,可以开多个客户端。本机测试通过,未做联机测试。

    server:

    using system.net;

    using system.net.sockets;

    using system.threading;

    using system.collections;

    namespace mysocketserver1

    {

        public partial class form1 : form

        {

            private ipaddress serverip = ipaddress.parse("127.0.0.1");//以本机作测试

            private ipendpoint serverfulladdr;//完整终端地址

            private socket sock;

            private system.timers.timer mytimer;

            private arraylist alsock;//当建立了多个连接时用于保存连接

            public form1()

            {

                initializecomponent();

            }

            private void btstart_click(object sender, eventargs e)

            {

                serverfulladdr = new ipendpoint(serverip, 1000);//取端口号1000

    //构造socket对象,套接字类型为“流套接字”,指定五元组中的协议元

                sock = new socket(addressfamily.internetwork, sockettype.stream,

    protocoltype.tcp);

    //指定五元组中的本地二元,即本地主机地址和端口号

                sock.bind(serverfulladdr);

    //监听是否有连接传入,指定挂起的连接队列的最大值为20

                sock.listen(20);

                alsock = new arraylist();

    //构造定时器,时间间隙为1秒,即每隔一秒执行一次accept()方法,以获取连接请求队列中//第一个挂起的连接请求

                mytimer =new system.timers.timer(1000);

                mytimer.elapsed +=new system.timers.elapsedeventhandler(mytimer_elapsed);

                mytimer.enabled = true;

            }

            private void mytimer_elapsed(object sender, system.timers.elapsedeventargs e)

            {

                mytimer.enabled = false;

    //执行accept(),当挂起队列为空时将阻塞本线程,同时由于上一语句,定时器将停止,直//至有连接传入

                socket acceptsock = sock.accept();

    //将accept()产生的socket对象存入arraylist

                alsock.add(acceptsock);

    // 构造threading.timer对象,这将导致程序另启线程。线程将执行回调函数,该委托限制//函数参数须为object型。threading.timer构造器的第二个参数即传入回调函数的参数;第//三个参数指定调用回调函数之前的延时,取0则立即启动;最后一个参数指定调用回调函数//的时间间隔,取0则只执行一次。

                system.threading.timer ti = new system.threading.timer(new

    timercallback(receivemsg), acceptsock, 0, 0);

                mytimer.enabled = true;

            }

            private void receivemsg(object obj)

            {

                socket acceptsock = (socket)obj;

                try

                {

                    while (true)

                    {

                        byte[] bytearray = new byte[100];

                        acceptsock.receive(bytearray);//接收数据

    //将字节数组转成字符串

                        string strrec = system.text.encoding.utf8.getstring(bytearray);

                        if (this.rtbreceive.invokerequired)

                        {

                            this.rtbreceive.invoke(new eventhandler(this.changericktextbox), new

    object[] { strrec, eventargs.empty });

                        }

                    }

                }

                catch(exception ex)

                {

                    acceptsock.close();

                    messagebox.show("s:receive message error"+ex.message);

                }

            }

            private void changericktextbox(object obj,eventargs e)

            {

                string s = system.convert.tostring(obj);

                this.rtbreceive.appendtext(s + environment.newline);

            }

            private void btsend_click(object sender, eventargs e)

            {

                socket sc=null;

                byte[] bytesend =

    system.text.encoding.utf8.getbytes(this.tbsend.text.tochararray());

                try

                {

    //同时存在若干个客户端连接时,在textbox1中输入要发送的是哪个连接

                    int index = int.parse(this.textbox1.text.trim());

                    sc = (socket)alsock[index - 1];

    //发送数据

                    sc.send(bytesend);

                }

                catch(exception ex)

                {

    if(sc != null)

    {

                    sc.close();

    }

                    messagebox.show("s:send message error"+ex.message);

                }

            }

            private void btclose_click(object sender, eventargs e)

            {

                try

                {

                    application.exit();

                }

                catch (exception ex)

                {

                    messagebox.show("s:close socket error" + ex.message);

                }

            }

        }

    }

    == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == ==

    client:

    using system.net;

    using system.net.sockets;

    using system.threading;

    namespace mysocketclient1

    {

        public partial class form1 : form

        {

            private ipaddress serverip = ipaddress.parse("127.0.0.1");

            private ipendpoint serverfulladdr;

            private socket sock;

            public form1()

            {

                initializecomponent();

            }

            private void btconnect_click(object sender, eventargs e)

            {

                try

                {

                    serverfulladdr = new ipendpoint(serverip, 1000);

                    sock = new socket(addressfamily.internetwork, sockettype.stream,

    protocoltype.tcp);

                    sock.connect(serverfulladdr);//建立与远程主机的连接

    //启动新线程用于接收数据

                    thread t = new thread(new threadstart(receivemsg));

                    t.name = "receive message";

    //一个线程或者是后台线程或者是前台线程。后台线程与前台线程类似,区别是后台线//程不会防止进程终止。一旦属于某一进程的所有前台线程都终止,公共语言运行库就//会通过对任何仍然处于活动状态的后台线程调用 abort 来结束该进程。

                    t.isbackground = true;

                    t.start();

                }

                catch(exception ex)

                {

                    messagebox.show(ex.message);

                }

            }

            private void receivemsg()

            {

                try

                {

                    while (true)

                    {

                        byte[] byterec = new byte[100];

                        this.sock.receive(byterec);

                        string strrec = system.text.encoding.utf8.getstring(byterec);

                        if (this.rtbreceive.invokerequired)

                        {

                            this.rtbreceive.invoke(new eventhandler(changertb), new object[]

    { strrec, eventargs.empty });

                        }

                    }

                }

                catch(exception ex)

                {

                    messagebox.show("receive message error"+ex.message);

                }

            }

            private void changertb(object obj, eventargs e)

            {

                string s = system.convert.tostring(obj);

                this.rtbreceive.appendtext(s + environment.newline);

            }

            private void btsend_click(object sender, eventargs e)

            {

                byte[] bytesend =

    system.text.encoding.utf8.getbytes(this.tbsend.text.tochararray());

                try

                {

                    this.sock.send(bytesend);

                }

                catch

                {

                    messagebox.show("send message error");

                }

            }

            private void btclose_click(object sender, eventargs e)

            {

                try

                {

                    this.sock.shutdown(socketshutdown.receive);

                    this.sock.close();

                    application.exit();

                }

                catch

                {

                    messagebox.show("exit error");

                }

            }

        }

    }

    不解之处:

    client端红色标注语句:this.sock.shutdown(socketshutdown.receive),如改成

    this.sock.shutdown(socketshutdown.both);或this.sock.shutdown(socketshutdown.send);

    则当点击cloce按钮时,cpu使用率疯涨到100%,而使用this.sock.shutdown(socketshutdown.receive);

    或不调用shutdown()方法则没有这个问题。难道客户端不应该用shutdown()?

    http://www.cnblogs.com/kissknife/archive/2006/08/13/475707.html


    文章整理:西部数码--专业提供域名注册、虚拟主机服务
    http://www.west263.com
    以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢

  • 相关阅读:
    解决不同浏览器文件下载文件名乱码问题(Java)
    zabbix常见问题
    axiosapi,js结构化定义、调用业务api接口。 no
    Java基础:反射小结
    Java基础:函数式编程的函数的本质
    Java基础:Java方法的签名的定义
    Java基础:异常怎么分类的(面试题:Exception和Error的区别),看完这篇就都捋清了
    编程类型和代表性语言
    Java基础:构造器小结
    ubuntu搭建wifi热点,共享网络,超简单
  • 原文地址:https://www.cnblogs.com/yellowapplemylove/p/2021586.html
Copyright © 2020-2023  润新知