利用晚上这点闲暇时间,写了一个Socket通信的小实例,该实例包含服务器端和客户端。其基本工作流程是:当服务器启动服务以后,客户端进行连接,如果连接成功,则用户可以在发送消息框中输入待发送的消息,然后点击“Send”按钮后向服务器发送消息,服务器在收到消息后立即向该客户端发送接收成功消息。其基本效果如图1.1和图1.2所示(注:下面两幅图于次日补上):

图1.1  服务器运行效果图

图1.2  客户端运行效果图

现将服务器和客户端部分代码贴出来,由于代码较简单,基本没有注释,并在此特别说明,该实例仅仅是一个简单的示例,其中的代码仍有进一步修改优化空间,同时亦欢迎各位朋友批评指正。
    服务器代码部分:
using System;
using System.Text;
using System.Windows.Forms;

using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace SocketServer
{
    public partial class frmServer : Form
    {
        private Thread m_serverThread;
        private Socket m_serverSocket;
        private string m_serverIP;
        private int m_serverPort;

public delegate void ReceiveMessageDelegate(Client client);
        ReceiveMessageDelegate receiveMessageDelegate;
        
        public frmServer()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
        }

private void frmServer_Load(object sender, EventArgs e)
        {
            string[] addresses = GetLocalAddresses();
            cmbIP.Items.Clear();
            if (addresses.Length > 0)
            {
                for (int i = 0; i < addresses.Length; i++)
                {
                    cmbIP.Items.Add(addresses[i]);
                }
                cmbIP.Text = (string)cmbIP.Items[0];
            }

txtPort.Text = "8899";
        }

private void btnStart_Click(object sender, EventArgs e)
        {
            m_serverIP = cmbIP.Text;
            m_serverPort = Int32.Parse(txtPort.Text);

Start();
            btnStart.Enabled = false;
            btnStop.Enabled = true;
        }

private void btnStop_Click(object sender, EventArgs e)
        {
            Stop();
            btnStart.Enabled = true;
            btnStop.Enabled = false;
        }

/// <summary>
        /// 开始服务
        /// </summary>
        private void Start()
        {
            try
            {
                m_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse(m_serverIP), m_serverPort);
                m_serverSocket.Bind(localEndPoint);
                m_serverSocket.Listen(10);

m_serverThread = new Thread(new ThreadStart(ReceiveAccept));
                m_serverThread.Start();

this.AddRunningInfo(">> " + DateTime.Now.ToString() + " Server started.");
            }
            catch (SocketException se)
            {
                throw new Exception(se.Message);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

/// <summary>
        /// 停止服务
        /// </summary>
        private void Stop()
        {
            try
            {
                m_serverThread.Abort(); // 线程终止
                m_serverSocket.Close(); // Socket Close

this.AddRunningInfo(">> " + DateTime.Now.ToString() + " Server stoped.");
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

private void ReceiveAccept()
        {
            while (true)
            {
                Client client = new Client();

try
                {
                    client.ClientSocket = m_serverSocket.Accept();
                    this.AddRunningInfo(">> " + DateTime.Now.ToString() + " Client[" + client.ClientSocket.RemoteEndPoint.ToString() + "] connected.");

receiveMessageDelegate = new ReceiveMessageDelegate(ReceiveMessages);
                    receiveMessageDelegate.BeginInvoke(client, ReceiveMessagesCallback, "");
                }
                catch (Exception ex)
                {
                    throw new Exception(ex.Message);
                }
            }
        }

private void ReceiveMessages(Client client)
        {
            while (true)
            {
                byte[] receiveBuffer = new byte[1024];

client.ClientSocket.Receive(receiveBuffer);

string strReceiveData = Encoding.Unicode.GetString(receiveBuffer);
                if (!string.IsNullOrEmpty(strReceiveData))
                {
                    this.AddRunningInfo(">> Receive data from [" + client.ClientSocket.RemoteEndPoint.ToString()+ "]:" + strReceiveData);
                    string strSendData = "OK. The content is:" + strReceiveData;
                    int sendBufferSize = Encoding.Unicode.GetByteCount(strSendData);
                    byte[] sendBuffer = new byte[sendBufferSize];
                    sendBuffer = Encoding.Unicode.GetBytes(strSendData);

client.ClientSocket.Send(sendBuffer);
                }
            }
        }

private void ReceiveMessagesCallback(IAsyncResult AR)
        {
            receiveMessageDelegate.EndInvoke(AR);
        }

/// <summary>
        /// 将运行信息加入显示列表
        /// </summary>
        private void AddRunningInfo(string message)
        {
            lstRunningInfo.BeginUpdate();
            lstRunningInfo.Items.Insert(0, message);

if (lstRunningInfo.Items.Count > 100)
            {
                lstRunningInfo.Items.RemoveAt(100);
            }

lstRunningInfo.EndUpdate();
        }

/// <summary>
        /// 获取本机地址列表
        /// </summary>
        public string[] GetLocalAddresses()
        {
            // 获取主机名
            string strHostName = Dns.GetHostName();

// 根据主机名进行查找
            IPHostEntry iphostentry = Dns.GetHostEntry(strHostName);

string[] retval = new string[iphostentry.AddressList.Length];

int i = 0;
            foreach (IPAddress ipaddress in iphostentry.AddressList)
            {
                retval[i] = ipaddress.ToString();
                i++;
            }
            return retval;
        } 
    }

/// <summary>
    /// 客户端会话信息类
    /// </summary>
    public class Client
    {
        Socket m_clientSocket;

public Client() { }

public Socket ClientSocket
        {
            get { return m_clientSocket; }
            set { this.m_clientSocket = value; }
        }
    }
}

客户端部分:
using System;
using System.Text;
using System.Windows.Forms;

using System.Net;
using System.Net.Sockets;

namespace SocketClient
{
    public partial class frmClient : Form
    {
        private Socket m_clientSocket;
        private byte[] m_receiveBuffer = new byte[1024];

public frmClient()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
        }

private void frmClient_Load(object sender, EventArgs e)
        {
            txtIP.Text = "172.18.20.234";
            txtPort.Text = "8899";
        }

/// <summary>
        /// 连接服务器
        /// </summary>
        private void btnConnect_Click(object sender, EventArgs e)
        {
            string serverIP = txtIP.Text;
            int serverPort = Int32.Parse(txtPort.Text);

m_clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Parse(serverIP),serverPort);

try
            {
                m_clientSocket.Connect(remoteEndPoint);
                if (m_clientSocket.Connected)
                {
                    m_clientSocket.BeginReceive(m_receiveBuffer, 0, m_receiveBuffer.Length, 0, new AsyncCallback(ReceiveCallBack), null);

btnConnect.Enabled = false;
                    btnDisconnect.Enabled = true;

this.AddRunningInfo(">> " + DateTime.Now.ToString() + " Client connect server success.");
                }
            }
            catch (Exception)
            {
                this.AddRunningInfo(">> " + DateTime.Now.ToString() + " Client connect server fail.");
                m_clientSocket = null;
            }
        }

/// <summary>
        /// 断开连接
        /// </summary>
        private void btnDisconnect_Click(object sender, EventArgs e)
        {
            if (m_clientSocket != null)
            {
                m_clientSocket.Close();

btnConnect.Enabled = true;
                btnDisconnect.Enabled = false;
                btnSend.Enabled = false;

this.AddRunningInfo(">> " + DateTime.Now.ToString() + " Client disconnected.");
            }
        }

/// <summary>
        /// 发送信息
        /// </summary>
        private void btnSend_Click(object sender, EventArgs e)
        {
            string strSendData = txtSend.Text;
            byte[] sendBuffer = new byte[1024];
            sendBuffer = Encoding.Unicode.GetBytes(strSendData);

if (m_clientSocket != null)
            {
                m_clientSocket.Send(sendBuffer);
            }
        }

private void ReceiveCallBack(IAsyncResult ar)
        {
            try
            {
                int REnd = m_clientSocket.EndReceive(ar);
                string strReceiveData = Encoding.Unicode.GetString(m_receiveBuffer, 0, REnd);
                this.HandleMessage(strReceiveData);
                m_clientSocket.BeginReceive(m_receiveBuffer, 0, m_receiveBuffer.Length, 0, new AsyncCallback(ReceiveCallBack), null);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

/// <summary>
        /// 处理接收到的数据
        /// </summary>
        private void HandleMessage(string message)
        {
            message = message.Replace("/0", "");
            if (!string.IsNullOrEmpty(message))
            {
                this.AddRunningInfo(">> Receive Data from server:" + message);
            }
        }

private void AddRunningInfo(string message)
        {
            lstRunningInfo.BeginUpdate();
            lstRunningInfo.Items.Insert(0, message);

if (lstRunningInfo.Items.Count > 100)
            {
                lstRunningInfo.Items.RemoveAt(100);
            }

lstRunningInfo.EndUpdate();
        }

private void txtSend_TextChanged(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(txtSend.Text) && m_clientSocket!=null)
            {
                btnSend.Enabled = true;
            }
            else
            {
                btnSend.Enabled = false;
            }
        }
    }
}

Socket 编程示例(二)的更多相关文章

  1. 多线程Java Socket编程示例

    package org.merit.test.socket; import java.io.BufferedReader; import java.io.IOException; import jav ...

  2. Linux学习之socket编程(二)

    Linux学习之socket编程(二) 1.C/S模型——UDP UDP处理模型 由于UDP不需要维护连接,程序逻辑简单了很多,但是UDP协议是不可靠的,实际上有很多保证通讯可靠性的机制需要在应用层实 ...

  3. Linux socket编程示例(最简单的TCP和UDP两个例子)

    一.socket编程 网络功能是Uinux/Linux的一个重要特点,有着悠久的历史,因此有一个非常固定的编程套路. 基于TCP的网络编程: 基于连接, 在交互过程中, 服务器和客户端要保持连接, 不 ...

  4. Java Socket编程示例

    一.Socket简介: 1.什么是Socket 网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket.Socket通常用来实现客户方和服务方的连接.Socket ...

  5. Python 基础之socket编程(二)

    Python 基础之socket编程(二) 昨天只是对socket编程做了简单的介绍,只是把socket通信的框架搭建起来,要对其中的功能进行进一步的扩充,就来看看今天的料哈! 一.基于tcp的套接字 ...

  6. JAVA Socket编程(二)之TCP通信

    基于TCP(面向连接)的socket编程,分为客户端和服务器端. 客户端的流程如下: (1)创建套接字(socket) (2)向服务器发出连接请求(connect) (3)和服务器端进行通信(send ...

  7. Python Socket 编程示例 Echo Server

    简评:我们已经从「Python Socket 编程概览」了解了 socket API 的概述以及客户端和服务器的通信方式,接下来让我们创建第一个客户端和服务器,我们将从一个简单的实现开始,服务器将简单 ...

  8. linux网络编程之socket编程(十二)

    今天继续学习socket编程,期待的APEC会议终于在京召开了,听说昨晚鸟巢那灯火通明,遍地礼花,有点08年奥运会的架势,有种冲动想去瞅见一下习大大的真容,"伟大的祖国,我爱你~~~&quo ...

  9. python之socket编程(二)

    标签(空格分隔): socket编程 SocketServer解析 SocketServer内部使用I/O多路复用,多线程,多进程来实现客户端多并发访问Socket服务端,while循环时使用I/O多 ...

随机推荐

  1. 转:PHP的(Thread Safe与Non Thread Safe)

    在安装xdebug到时候你会有有TS和NTS版本的选择,在以前还有VC6和VC9的版本.如果你没有根据你目前的服务器的状况选择对应的版本的话,那么xdebug是安装不成功的. 一.如何选择 php5. ...

  2. windows中.msc文件详解

    msc是Microsoft Management Console的缩写.其实是一种可执行程序类型,可.exe类似.一般可以通过直接双击.msc文件或者在windows的运行中输入相应的文件名来启动. ...

  3. Net-Snmp安装配置

    1. 下载安装 net-snmp安装程序:net-snmp-5.4.2.1-1.win32.exe Perl安装程序:ActivePerl-5.10.0.1004-MSWin32-x86-287188 ...

  4. Majority Element 解答

    Solution 1 Naive way First, sort the array using Arrays.sort in Java. Than, scan once to find the ma ...

  5. 【HDU1231】How Many Tables(并查集基础题)

    什么也不用说,并查集裸题,直接盲敲即可. #include <iostream> #include <cstring> #include <cstdlib> #in ...

  6. 详解JavaScript中的Object对象

    Object是在javascript中一个被我们经常使用的类型,而且JS中的所有对象都是继承自Object对象的.虽说我们平时只是简单地使用了Object对象来存储数据,并没有使用到太多其他功能,但是 ...

  7. IOS消息推送情况总结

      App没有启动的时候,接受到了消息通知.这个时候操作系统会按默认方式来展示一个alert,在App Icon上标记一个数字 .当程序处于关闭状态收到推送消息时,点击图标或消息栏会调用 - (BOO ...

  8. Android学习总结——TextView跑马灯效果

    Android系统中TextView实现跑马灯效果,必须具备以下几个条件: 1.android:ellipsize="marquee" 2.TextView必须单行显示,即内容必须 ...

  9. AC Milan VS Juventus(模拟)

    AC Milan VS Juventus Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Oth ...

  10. 【转】invokeRequired属性和 invoke()方法

    C#中禁止跨线程直接访问控件,InvokeRequired是为了解决这个问题而产生的,当一个控件的InvokeRequired属性值为真时,说明有一个创建它以外的线程想访问它. 此时它将会在内部调用n ...