c# winform 实现客户端和服务器端互相交互

服务器端的代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
        }

        private void tbPortNum_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar > 31)
                if (e.KeyChar < 48 || e.KeyChar > 57)
                {
                    MessageBox.Show("输入非法字符!", "警告!");
                    tbPortNum.Text = "";
                }
            if (tbPortNum.Text != "")
            {
                btCreServer.Enabled = true;
            }
        }

        // private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
        //{

        //}

        //获取本机的IP
        //获取本机的IP
        public Boolean SocketIsConnected(Socket soc)
        {
            Boolean isconnected = false;
            try
            {

                soc.Send(System.Text.Encoding.Default.GetBytes("hello!"));
                isconnected = true;
            }

            catch
            {
                isconnected = false;
            }

            return isconnected;

        }

        public string GetLocalIP()
        {

            IPAddress[] AddressList = Dns.GetHostAddresses(Dns.GetHostName());
            return AddressList[1].ToString();

        }

        Socket sock;          //定义一个Socket类的对象 (默认为protected)
        Thread th;             //定义一个Thread类的对象
        Socket newSock;
        //BackgroundWorker bgw = new BackgroundWorker();
        private void BeginListen()               //Socket监听函数, 等下作为创建新线程的参数
        {

            IPAddress serverIp = IPAddress.Parse(GetLocalIP());         //调用本类静态函数GetLocalIP得到本机IPAddress.
            IPEndPoint iep = new IPEndPoint(serverIp, Convert.ToInt32(tbPortNum.Text));    //本地终结点
            sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);   //实例化内成员sock
            // Boolean BuildSocketAccept=false ;
            // bgw.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
            //bgw.RunWorkerAsync(bs);
            //this.label1.Text = iep.ToString();

            sock.Bind(iep);                                  //Socket类的一个重要函数, 绑定一个IP,
            while (true)                     //这里弄了个死循环来监听端口, 有人会问死循环了,那程序不卡住了, 注意这只是个类, 这里还没有main函数呢.
            {
                try
                {
                    sock.Listen(10);             //好了,sock绑定了本地终结点就可以开始监听了,5表示最大连接数为5
                    newSock = sock.Accept();     //这里又有Socket类的一个重要的方法:Accept, 该方法接受来自外面的Socket连接请求, 并返回一个Socket套接字, 这个套接字就开始处理这一个client与Server之间的对话
                    BackgroundWorker bgwClintIP = new BackgroundWorker();
                    bgwClintIP.DoWork += new DoWorkEventHandler(bgWorker_DoWorkClintIP);
                    //bgwClintIP.RunWorkerAsync(System.Text.Encoding.Default.GetBytes(newSock.RemoteEndPoint.ToString()));
                    if (!SocketIsConnected(newSock))
                    {
                        MessageBox.Show("连接已断开!");
                        break;

                    }
                    while (true)
                    {
                        try
                        {
                            Byte[] byteMessage = new Byte[100]; //存放消息的字节数组缓冲区, 注意数组表示方法,和C不同的.
                            newSock.Receive(byteMessage); //接受client发送过来的数据保存到缓冲区.
                            BackgroundWorker bgw = new BackgroundWorker();
                            bgw.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
                            bgw.RunWorkerAsync(byteMessage);
                        }
                        catch
                        {

                        }

                    }

                }
                catch (SocketException se)              //捕捉异常,
                {
                    MessageBox.Show(se.ToString());
                    //lbState.Text = se.ToString();       //将其显示出来, 在此亦可以自定义错误.
                }
            }
        }
        private void bgWorker_DoWorkClintIP(object sender, DoWorkEventArgs e)
        {
            byte[] bs = (byte[])e.Argument;
            string r1 = Encoding.Default.GetString(bs);
            //RevDataList.BeginInvoke(new System.EventHandler(ShowGetByte), r1);
            this.BeginInvoke(new System.EventHandler(AddClintIPPage), r1);

        }
        private void AddClintIPPage(object o, System.EventArgs e)
        {

            lbClintIP.Text = o.ToString();
            lbState.Text = "已建立连接";
            tbRecMSG.AppendText("\r\n" + "建立连接:" + o.ToString());

        }
        private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            byte[] bs = (byte[])e.Argument;
            string r1 = Encoding.Default.GetString(bs);
            //RevDataList.BeginInvoke(new System.EventHandler(ShowGetByte), r1);
            this.BeginInvoke(new System.EventHandler(ShowGetByte), r1);
        }
        private void ShowGetByte(object o, System.EventArgs e)
        {

            tbRecMSG.AppendText("\r\n" + lbClintIP.Text + "客户端:" + o.ToString());

        }

        private void btCreServer_Click(object sender, EventArgs e)
        {

            if (btCreServer.Text == "设立服务器")
            {
                btCreServer.Text = "关闭服务器";
                tbPortNum.Enabled = false;
                lbLocalIP.Text = "本地IP:" + GetLocalIP();

                try
                {
                    th = new Thread(new ThreadStart(BeginListen));          //创建一个新的线程专门用于处理监听,这句话可以分开写的,比如: ThreadStart ts=new ThreadStart(BeginListen); th=new Thread (ts); 不过要注意, ThreadStart的构造函数的参数一定要是无参数的函数. 在此函数名其实就是其指针, 这里是委托吗?
                    th.Start();                            //启动线程
                    lbState.Text = "状态:正在监听";
                }
                catch (SocketException se)           //处理异常
                {
                    MessageBox.Show(se.Message, "出现问题", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                catch (ArgumentNullException ae)   //参数为空异常
                {
                    lbState.Text = "参数错误";
                    MessageBox.Show(ae.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }

            else
            {
                btCreServer.Text = "建立服务器";
                tbPortNum.Enabled = true;
                sock.Close();                     //关闭套接字
                th.Abort();                         //终止监听线程
                lbState.Text = "状态:停止监听";
            }
        }

        private void btSendMSG_Click(object sender, EventArgs e)
        {

            if (newSock == null)
                MessageBox.Show("尚未建立连接,发送失败!");
            else if (tbSendMSG.Text == "")
                MessageBox.Show("输入为空,发送失败!");
            else
            {
                try
                {

                    newSock.Send(System.Text.Encoding.Default.GetBytes(tbSendMSG.Text));
                    tbRecMSG.AppendText("\r\n" + "服务器端:" + tbSendMSG.Text);
                }

                catch (ArgumentNullException ae)
                {
                    MessageBox.Show(ae.Message, "参数为空", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
                }
                catch (SocketException se)
                {
                    MessageBox.Show(se.Message, "出现问题", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            tbSendMSG.Text = "";
        }

        private void tbPortNum_TextChanged(object sender, EventArgs e)
        {

        } 

        private void tbRecMSG_TextChanged(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            tbRecMSG.Text = "";
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

    }

}

客户端的代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Threading;
using System.Net;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public Boolean SocketIsConnected(Socket soc)
        {
            Boolean isconnected = false;
            try
            {

                soc.Send(System.Text.Encoding.Default.GetBytes("$"));
                isconnected = true;
            }

            catch
            {
                isconnected = false;
            }

            return isconnected;

        }

        private Socket sock;          //定义一个Socket类的对象 (默认为protected)
        Thread th;             //定义一个Thread类的对象
        //Socket newSock;

        private void BeginListen()               //Socket监听函数, 等下作为创建新线程的参数
        {
            int Port = int.Parse(textPort.Text);
            IPAddress ip = IPAddress.Parse(textIp.Text);         //调用本类静态函数GetLocalIP得到本机IPAddress.
            IPEndPoint ipp = new IPEndPoint(ip, Port);

            //IPEndPoint iep = new IPEndPoint(serverIp, Convert.ToInt32(tbPortNum.Text));    //本地终结点
            sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);   //实例化内成员sock
            sock.Connect(ipp);    //连接服务器

            // if (!SocketIsConnected(sock))
            //{
            //    lbState.Text="连接已断开!";
            //    return;
            //}
            //else
            //{
            //    //lbState.Text = "也连接到服务器!";

            //}
           do
           {
                    Byte[] byteMessage = new Byte[100]; //存放消息的字节数组缓冲区, 注意数组表示方法,和C不同的.
                    sock.Receive(byteMessage); //接受Server发送过来的数据保存到缓冲区.
                    BackgroundWorker bgw = new BackgroundWorker();
                    bgw.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
                    bgw.RunWorkerAsync(byteMessage);

           }while(true);

        }

        private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            byte[] bs = (byte[])e.Argument;
            string r1 = Encoding.Default.GetString(bs);
            //RevDataList.BeginInvoke(new System.EventHandler(ShowGetByte), r1);
            this.BeginInvoke(new System.EventHandler(ShowGetByte), r1);
        }
        private void ShowGetByte(object o, System.EventArgs e)
        {

            //textRec.AppendText("\r\n" + lbClintIP.Text + ‘Server:‘ + o.ToString());
            textRec.AppendText("\r\n" + "服务器端:" + o.ToString());

        }

        //当点击连接服务器的时候
        private void btConnectServer_Click(object sender, EventArgs e)
        {
            if (btConnectServer.Text == "连接服务器")
            {
                btConnectServer.Text = "断开连接";
                textIp.Enabled = false;
                textPort.Enabled = false;
                //lbLocalIP.Text = "本地IP:" + GetLocalIP();

                try
                {
                    th = new Thread(new ThreadStart(BeginListen));          //创建一个新的线程专门用于处理监听,这句话可以分开写的,比如: ThreadStart ts=new ThreadStart(BeginListen); th=new Thread (ts); 不过要注意, ThreadStart的构造函数的参数一定要是无参数的函数. 在此函数名其实就是其指针, 这里是委托吗?
                    th.Start();                            //启动线程

                }
                catch (SocketException se)           //处理异常
                {
                    MessageBox.Show(se.Message, "出现问题", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                catch (ArgumentNullException ae)   //参数为空异常
                {
                    lbState.Text = "参数错误";
                    MessageBox.Show(ae.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }
            else
            {
                btConnectServer.Text = "连接服务器";
                textIp.Enabled = true;
                textPort.Enabled = true;
                sock.Close();                     //关闭套接字
                th.Abort();                         //终止监听线程

            }
        }

        private void btSend_Click(object sender, EventArgs e)
        {
            if (sock == null)
                MessageBox.Show("尚未建立连接,发送失败!");
            else if (textSend.Text == "")
                MessageBox.Show("输入为空,发送失败!");
            else
            {
                try
                {

                    sock.Send(System.Text.Encoding.Default.GetBytes(textSend.Text));
                    textRec.AppendText("\r\n" + "客户端:" + textSend.Text);
                }

                catch (ArgumentNullException ae)
                {
                    MessageBox.Show(ae.Message, "参数为空", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
                }
                catch (SocketException se)
                {
                    MessageBox.Show(se.Message, "出现问题", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            textSend.Text = "";
        }

        private void textIp_TextChanged(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            textRec.Text = "";
        }

    }
}
时间: 2024-10-29 04:55:42

c# winform 实现客户端和服务器端互相交互的相关文章

客户端与服务器端的交互

客户端和服务器端的交互模型: 客户端发送请求 -> 服务器端接收请求 -> 服务端准备数据内容 ->服务器端把内容返回给客户端 -> 客户端接收返回的内容 -> 客户端进行解析渲染 客户端传递给服务器端的内容以及服务器端传递给客户端的内容都是由HTTP等这种传输协议完成的

Android客户端和服务器端数据交互

网上有很多例子来演示Android客户端和服务器端数据如何实现交互不过这些例子大多比较繁杂,对于初学者来说这是不利的,现在介绍一下代码最简单.逻辑最清晰的交互例子: 一.服务器端: 二.Android手机客户端:

Android客户端和服务器端数据交互的第二种方法

网上有很多例子来演示Android客户端和服务器端数据如何实现交互不过这些例子大多比较繁杂,对于初学者来说这是不利的,现在介绍几种代码简单.逻辑清晰的交互例子,本篇博客介绍第二种: 一.服务器端: 代码1:添加名为"AndroidServerServlet.java"的文件 package com.ghj.packageofservlet; import java.io.IOException; import java.io.PrintWriter; import javax.serv

Android客户端和服务器端数据交互的第三种方法

网上有很多例子来演示Android客户端和服务器端数据如何实现交互不过这些例子大多比较繁杂,对于初学者来说这是不利的,现在介绍几种代码简单.逻辑清晰的交互例子,本篇博客介绍第三种: 一.服务器端: 代码1:添加名为"AndroidServerServlet.java"的文件 package com.ghj.packageofservlet; import java.io.IOException; import java.io.PrintWriter; import javax.serv

Android客户端和服务器端数据交互的第四种方法

网上有很多例子来演示Android客户端和服务器端数据如何实现交互不过这些例子大多比较繁杂,对于初学者来说这是不利的,现在介绍几种代码简单.逻辑清晰的交互例子,本篇博客介绍第四种: 一.服务器端: 代码1:添加名为"AndroidServerServlet.java"的文件 package com.ghj.packageofservlet; import java.io.IOException; import java.io.PrintWriter; import javax.serv

浅析Java web程序之客户端和服务器端交互原理(转)

转载自http://www.cnblogs.com/lys_013/archive/2012/05/05/2484561.html 1. 协议 a. TCP/IP整体构架概述 TCP/IP协议并不完全符合OSI的七层参考模型.传统的开放式系统互连参考模型,是一种通信协议的7层抽象的参考模型,其中每一层执行某一特定任务. 该模型的目的是使各种硬件在相同的层次上相互通信.这7层是:物理层.数据链路层.网路层.传输层.话路层.表示层和应用层.而TCP/IP通讯协议采用 了4层的层级结构,每一层都呼叫它

[转]HTTP报文接口及客户端和服务器端交互原理

1. 协议 a. TCP/IP整体构架概述 TCP/IP协议并不完全符合OSI的七层参考模型.传统的开放式系统互连参考模型,是一种通信协议的7层抽象的参考模型,其中每一层执行某一特定任务.该模型的目的是使各种硬件在相同的层次上相互通信.这7层是:物理层.数据链路层.网路层.传输层.话路层.表示层和应用层.而TCP/IP通讯协议采用了4层的层级结构,每一层都呼叫它的下一层所提供的网络来完成自己的需求.这4层分别为: i. 应用层:应用程序间沟通的层,如超文本传送协议(HTTP).简单电子邮件传输(

封装一个类搞定90%安卓客户端与服务器端交互

本实例封装了一个处理安卓客户端与服务器端交互的几个方法,对于中文乱码问题本实例也找到了解决方案.本例可以处理的场景如下: 1.与服务器端交互json数据. 2.Get方式与服务器端交互数据. 3.Post方式与服务器端交互数据. 4.HttpClient方式与服务器端交互数据. 5.上传文件到服务器端. 6.从服务器端下载文件. 7.从服务器端读取文本文件. 实例截图: 本篇文章将实例代码完整贴出,希望以本文作为一个交流的平台,大家集思广益封装出更好的处理类.交流地址: http://blog.

zookeeper原理解析-客户端与服务器端交互

Zookeeper集群中server数量总是确定的,所以集群中的server交互采用比较可靠的bio长连接模型:不同于集群中sever间交互zookeeper客户端其实数量是未知的,为了提高zookeeper并发性能,zookeeper客户端与服务器端交互采用nio模型.下面我们主要来讲讲zookeeper的服务器端与客户端的交互.读者对nio不了解的话不妨抽点时间去了解下,对于一些nio框架如netty,mina再如一些web容器如tomcat,jetty底层都实现一套nio框架,对于实现ni