using System;
using System.Net;
/// <summary>
/// 客户端通过TCP/IP连接服务端的方法,包含连接,发送数据,接收数据功能
/// </summary>
using System.Net.Sockets;
using System.Text;
using System.Threading;
public class LYL_TCP_Client
{
// 定义一个空的Socket对象
Socket socket = null; // 当一个异步操作完成时, 用于通知的事件对象
//创建一个手动线程通知事件,false表示默认是线程阻塞,true表示线程继续,只有线程继续WaitOne()才有意义
static ManualResetEvent clientDone = new ManualResetEvent(false); // 异步操作超过时间定义. 如果在此时间内未接收到回应, 则放弃此操作.
const int TIMEOUT_MILLISECONDS = 5000; // 用于接收数据的缓存数组大小
const int MAX_BUFFER_SIZE = 1024; /// <summary>
/// 通过给定的地址和端口尝试TCP连接
/// </summary>
/// <param name="hostName">主机地址</param>
/// <param name="portNumber">通讯端口</param>
/// <returns>返回一个以字符串形式表示的连接结果</returns>
public string Connect(string hostName, int portNumber)
{
//连接结果,预定义为空
string result = string.Empty; //通过给定的地址和端口创建一个网络终结点
DnsEndPoint hostEntry = new DnsEndPoint(hostName, portNumber); // 给预定义的空的Socket对象赋值
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // 创建一个SocketAsyncEventArgs 异步操作对象用于连接请求
SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
//设置异步操作的DNS终结点
socketEventArg.RemoteEndPoint = hostEntry; // Inline event handler for the Completed event.
// Note: This event handler was implemented inline in order to make this method self-contained.
socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
{
// 获取连接结果
result = e.SocketError.ToString(); //标识请求已经完成, 不阻塞 UI 线程
clientDone.Set();
}); // 重置clientDone,导致线程阻塞
clientDone.Reset(); // socket异步连接请求
socket.ConnectAsync(socketEventArg); //阻塞UI线程,等待下一个线程,如超过指定时间则认为已经超时并开启UI线程
clientDone.WaitOne(TIMEOUT_MILLISECONDS); //返回连接结果
return result;
} /// <summary>
/// 发送指令数据至服务器
/// </summary>
/// <param name="data">要发送的指令</param>
/// <returns>发送结果,即成功或失败</returns>
public string Send(string data)
{
string response = "Operation Timeout"; // 使用在连接操作初始化的socket对象进行数据发送
if (socket != null)
{
// 创建 SocketAsyncEventArgs 对象、并设置对象属性
SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
socketEventArg.RemoteEndPoint = socket.RemoteEndPoint;
socketEventArg.UserToken = null; // 事件完成监听器
socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
{
response = e.SocketError.ToString(); //不阻塞UI线程
clientDone.Set();
}); // 将需要发送的数据指令送入发送缓冲区
byte[] payload = Encoding.Unicode.GetBytes(data);
socketEventArg.SetBuffer(payload, 0, payload.Length); // 表示事件未完成,导致线程阻塞
clientDone.Reset(); // socket异步连接请求
socket.SendAsync(socketEventArg); // 阻塞UI线程,等待下一个线程,如超过指定时间则认为已经超时并开启UI线程
clientDone.WaitOne(TIMEOUT_MILLISECONDS);
}
else
{
response = "Socket is not initialized";
} return response;
} public string Receive()
{
string reciveString = "";//服务端返回的整一串字符串,有可能包含有多个包
string oneTimeReciveString = "";//一次接收到的字符串,当有多个数据包的时候,每次只接收一个包 while (true)
{
oneTimeReciveString = OneTimeReceive();
Thread.Sleep(50);//线程等待,避免网络状况不好导致接收不完全
if (oneTimeReciveString.Length > 0)
{
reciveString = reciveString + oneTimeReciveString;
}
else
break;
}
return reciveString;
}
/// <summary>
/// 从服务端接收数据,此方法每次只接收一个数据包
/// </summary>
/// <returns>一个数据包</returns>
public string OneTimeReceive()
{
string response = "Operation Timeout"; if (socket != null)
{
// 创建 SocketAsyncEventArgs 对象、并设置对象属性
SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
socketEventArg.RemoteEndPoint = socket.RemoteEndPoint; // 设置接收数据缓冲区
socketEventArg.SetBuffer(new Byte[MAX_BUFFER_SIZE], 0, MAX_BUFFER_SIZE); // Inline event handler for the Completed event.
// Note: This even handler was implemented inline in order to make
// this method self-contained.
socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
{ if (e.SocketError == SocketError.Success)
{
// 从接收缓冲区得到数据
response = Encoding.Unicode.GetString(e.Buffer, e.Offset, e.BytesTransferred); //去除缓冲区多余的字节,即当返回数据的长度比缓冲字节数组小的时候,去除掉缓冲自己数组中有用数据外的字符
//数组中默认的字符为'\0'
response = response.Trim('\0');
}
else
{
response = e.SocketError.ToString();
}
clientDone.Set(); }); //表示事件未完成,导致线程阻塞
clientDone.Reset(); //socket异步连接请求
socket.ReceiveAsync(socketEventArg); //阻塞UI线程,等待下一个线程,如超过指定时间则认为已经超时并开启UI线程
clientDone.WaitOne(TIMEOUT_MILLISECONDS);
}
else
{
response = "Socket is not initialized";
} return response;
} /// <summary>
/// 关闭socket并释放资源
/// </summary>
public void Close()
{
if (socket != null)
{
socket.Close();
}
} }

  

wp socket tcp链接的更多相关文章

  1. socket 关于同一条TCP链接数据包到达顺序的问题

    转:http://blog.csdn.net/l1008610/article/details/52197602 以前作者也一直以为数据包先发的不一定先到,直到今天才意识这个问题的缺陷,数据包是不一定 ...

  2. 使用SOCKET TCP

    刚刚接触SOCKET编程,网上看了一些资料,发现做些简单的应用还是不难.但是要深入了解SOCKET编程还需要系统的看一些书.一般在进程间通信TCP是一种不错的方式. ---XXX TCP链接是面向流的 ...

  3. Socket TCP Server一个端口可以有多少个长连接?受到什么影响?linux最大文件句柄数量总结

    Socket TCP Server一个端口可以有多少个长连接? 网上答案很多,不知道那个才是正确的 理论上是无限的 16.Linux中,一个端口能够接受tcp链接数量的理论上限是? A.1024 B. ...

  4. 27.Socket,TCP,UDP,HTTP基本通信原理

    Socket,TCP,UDP,HTTP基本通信原理(摘自百度): TCP.UDP,HTTP 底层通信都是通过 socket 套接字实现 网络上不同的计算机,也可以通信,那么就得使用网络套接字(sock ...

  5. ss is one another utility to investigate sockets(特适合大规模tcp链接)

    原创文章,转载请注明: 转载自系统技术非业余研究 本文链接地址: ss is one another utility to investigate sockets(特适合大规模tcp链接) 具体的可以 ...

  6. iOS Socket/Tcp编程 GCDAsyncSocket的实战(带回调)

    很多同学一听到Socket TCP UDP 这几个字眼感觉特别害怕,很怕在工作当中使用,因为他们太底层了.下面我把我在工作中使用Socket类库GCDAsyncSocket进行一次实战 文章中只适用于 ...

  7. Lib1vent:10链接监听器接受TCP链接

    evconnlistener机制提供了监听并接受TCP链接的方法.除非特别注明,本章的所有函数和类型都在event2/listener.h中声明. 一:创建或释放evconnlistener stru ...

  8. 从Linux源码看Socket(TCP)的bind

    从Linux源码看Socket(TCP)的bind 前言 笔者一直觉得如果能知道从应用到框架再到操作系统的每一处代码,是一件Exciting的事情. 今天笔者就来从Linux源码的角度看下Server ...

  9. 分布式消息总线,基于.NET Socket Tcp的发布-订阅框架之离线支持,附代码下载

    一.分布式消息总线以及基于Socket的实现 在前面的分享一个分布式消息总线,基于.NET Socket Tcp的发布-订阅框架,附代码下载一文之中给大家分享和介绍了一个极其简单也非常容易上的基于.N ...

随机推荐

  1. 静态方法staticmethod类方法classmethod

    静态方法 只是名义上归类管理,实际上在静态方法里访问不了类或者实例中的任何属性. 类方法 只能访问类变量,不能访问实例变量 属性方法 把一个方法变成一个静态属性,调用的时候不能加() 如果这种属性方法 ...

  2. xml处理模块

    xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,大家只能选择用xml呀,至今很多传统公司如金融行业的很多系统的 ...

  3. vsftpd设置被动模式

    完整配置 listen=yes listen_port= max_clients= max_per_ip= local_max_rate= anonymous_enable=no local_enab ...

  4. 第十八章 MySQL Workbench5.2使用(待续)

    ··········

  5. FB联网无人机取得重大进展 实现首次成功着陆

    科技讯6月30日消息,据Engadget报道,在过去的几年里,世界最大社交网络Facebook始终在测试其太阳能无人飞机Aquila.2016年6月份,这种联网无人机在美国亚利桑那州的尤马进行了首次全 ...

  6. Aptana Studio 3 如何汉化,实现简体中文版

    这篇文章写了又一年多的时间了,哈哈,今天更新一次 此处修正的下面教程的[第五步]Babel Language Pack Update Site for Helioshttp://download.ec ...

  7. puclic 页面公共CSS样式

    body, div, dl, dt, dd, ul, ol, li, pre, form, fieldset, blockquote, h1, h2, h3, h4, h5, h6,p{ paddin ...

  8. mysql忘记root密码的处理方法

    在linux下,如果忘记了mysql中root用户的密码可以采用以下办法解决. 1. 修改my.cnf,加入skip-grant-tables 修改mysql的配置文件my.cnf,在[mysqld] ...

  9. Linux系统设置Samba共享笔记

    # "不允许一个用户使用一个以上用户名与服务器或共享资源的多重连接" C: 之前曾经与主机成功进行连接,连接断开后未将连接状态清除 $: net use */del /y # &q ...

  10. ansible基本使用

    ansible介绍 基础概念 ansible是个配置管理工具,可以批量处理一些任务.ansible只需要依赖ssh即可使用,而不需要在受管主机上安装客户端工具. ansible具有幂等性,即以结果为导 ...