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. mysql索引之六:mysql高效索引之覆盖索引

    概念 如果索引包含所有满足查询需要的数据的索引成为覆盖索引(Covering Index),也就是平时所说的不需要回表操作 判断标准 使用explain,可以通过输出的extra列来判断,对于一个索引 ...

  2. Avro之二:入门demo

    一.使用avro-maven插件为avsc文件生成对应的java类: 在项目的pom.xml中增加依赖及插件如下: <dependency> <groupId>org.apac ...

  3. Android Binder机制中的异步回调

    “Binder通信是同步而不是异步的”,但是在实际使用时,是设计成客户端同步而服务端异步. 看看Framwork层的各service类java源码便会知道,在客户端调用服务端的各种方法时,通常会传递一 ...

  4. 安全测试之session,cookie

    session session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息.•但程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这 ...

  5. IDA Pro 权威指南学习笔记(二) - IDA 数据库文件

    生成数据库文件 把要分析的文件用 IDA 打开后,会生成 3 个数据库文件 扩展名分别为 .id0,id1,nam .id0 文件是一个二叉树形式的数据库 .id1 文件包含描述每个程序字节的标记 . ...

  6. 【树莓派智能门锁】使用脚本控制GPIO来开锁【4】

    假定你已经通过此文章或者其他方式完成了树莓派的基本配置 [树莓派]RASPBIAN镜像初始化配置 我们通过VNC View连接到树莓派查看一下~ 1.更新一下基本的设置:更新一下源,把python-d ...

  7. Python时间日期函数讲解

    所有日期.时间的api都在datetime模块内. 1. 日期输出格式化 datetime => string import datetime now = datetime.datetime.n ...

  8. pycharm的自定义python模板

    #!/usr/bin/env python # encoding: utf-8 #set( $SITE = "http://blog.csdn.net/morgana" ) &qu ...

  9. Android控件使用自定义字体

    我们不可能只满足于系统自带的字体(太丑),其实控件自定义字体也很简单.. 1.首先找到该字体的ttf文件. 2.把字体文件放在scr/mian/assets/fonts下,如果没有该路径则自己创建. ...

  10. 企业短信通 C# HTTP接口 发送短信

    /* 功能: 企业短信通 C# HTTP接口 发送短信 修改日期: 2014-09-01 说明: http://api.cnsms.cn/?ac=send&uid=用户账号&pwd=M ...