Socket 编程示例(二)
利用晚上这点闲暇时间,写了一个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 编程示例(二)的更多相关文章
- 多线程Java Socket编程示例
package org.merit.test.socket; import java.io.BufferedReader; import java.io.IOException; import jav ...
- Linux学习之socket编程(二)
Linux学习之socket编程(二) 1.C/S模型——UDP UDP处理模型 由于UDP不需要维护连接,程序逻辑简单了很多,但是UDP协议是不可靠的,实际上有很多保证通讯可靠性的机制需要在应用层实 ...
- Linux socket编程示例(最简单的TCP和UDP两个例子)
一.socket编程 网络功能是Uinux/Linux的一个重要特点,有着悠久的历史,因此有一个非常固定的编程套路. 基于TCP的网络编程: 基于连接, 在交互过程中, 服务器和客户端要保持连接, 不 ...
- Java Socket编程示例
一.Socket简介: 1.什么是Socket 网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket.Socket通常用来实现客户方和服务方的连接.Socket ...
- Python 基础之socket编程(二)
Python 基础之socket编程(二) 昨天只是对socket编程做了简单的介绍,只是把socket通信的框架搭建起来,要对其中的功能进行进一步的扩充,就来看看今天的料哈! 一.基于tcp的套接字 ...
- JAVA Socket编程(二)之TCP通信
基于TCP(面向连接)的socket编程,分为客户端和服务器端. 客户端的流程如下: (1)创建套接字(socket) (2)向服务器发出连接请求(connect) (3)和服务器端进行通信(send ...
- Python Socket 编程示例 Echo Server
简评:我们已经从「Python Socket 编程概览」了解了 socket API 的概述以及客户端和服务器的通信方式,接下来让我们创建第一个客户端和服务器,我们将从一个简单的实现开始,服务器将简单 ...
- linux网络编程之socket编程(十二)
今天继续学习socket编程,期待的APEC会议终于在京召开了,听说昨晚鸟巢那灯火通明,遍地礼花,有点08年奥运会的架势,有种冲动想去瞅见一下习大大的真容,"伟大的祖国,我爱你~~~&quo ...
- python之socket编程(二)
标签(空格分隔): socket编程 SocketServer解析 SocketServer内部使用I/O多路复用,多线程,多进程来实现客户端多并发访问Socket服务端,while循环时使用I/O多 ...
随机推荐
- Light OJ 1095 Arrange the Numbers(容斥)
给定n,m,k,要求在n的全排列中,前m个数字中恰好有k个位置不变,有几种方案?首先,前m个中k个不变,那就是C(m,k),然后利用容斥原理可得 ans=ΣC(m,k)*(-1)^i*C(m-k,i) ...
- boost库使用:vs2013下boost::container::vector编译出错解决
boost版本:boost_1_55_0 bug报告地址 https://svn.boost.org/trac/boost/ticket/9332 出错信息 has_member_function_c ...
- 【转】Android 源码下利用jni编译自己的项目(参考系统development/samples/SimpleJNI)
原文网址:http://blog.csdn.net/qiuxiaolong007/article/details/7860481 记于正文前:环境是ubuntu10.10,android 源码是2.0 ...
- CF 578A A Problem about Polyline
题意: There is a polyline going through points (0, 0) – (x, x) – (2x, 0) – (3x, x) – (4x, 0) – ... - ( ...
- 《Java程序员面试笔试宝典》之volatile有什么作用
在由Java语言编写的程序中,有时候为了提高程序的运行效率,编译器会自动对其进行优化,把经常被访问的变量缓存起来,程序在读取这个变量的时候有可能会直接从缓存(例如寄存器)中来读取这个值,而不会去内存中 ...
- LinqToXML~读XML文件续
上篇文章读了如何通过linq to xml去读取XML文件,而这讲主要通过linq to xml来读取由属性组件的XML文件,例如读取一个web.config的XML格式的配置文件,下面是config ...
- Linux shell编程 4 ---- shell中的循环
1 for循环 1 for语句的结构 for variable in values; do statement done 2 for循环通常是用来处理一组值,这组值可以是任意的字符串的集合 3 for ...
- Tomcat 内存与优化篇
Tomcat 内存与优化一.Tomcat 运行环境介绍 1.Tomcat 本身无法直接在计算机上运行,需要依赖硬件基础上的操作系统和Java虚拟机: 2.Java 程序启动时JVM都会分配一个初始内存 ...
- HTTP协议2之基本认证--转
http协议是无状态的, 浏览器和web服务器之间可以通过cookie来身份识别. 桌面应用程序(比如新浪桌面客户端)跟Web服务器之间是如何身份识别呢? 什么是HTTP基本认证 桌面应用程序也通过H ...
- css3实现手机菜单展开收起动画
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...