博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于.NET Socket API 通信的综合应用
阅读量:4678 次
发布时间:2019-06-09

本文共 9972 字,大约阅读时间需要 33 分钟。

闲谈一下,最近和客户进行对接Scoket 本地的程序作为请求方以及接受方,对接Scoket 的难度实在比较大,因为涉及到响应方返回的报文的不一致性,对于返回的报文的格式我需要做反序列化的难度增大了不少,下面我就谈谈如果基于进行对接Scoket API 的接口的。方便大家,节省时间,少走弯路。大大的提高自己的开发的效率,当然我介绍的只是基于.NET Scoket API 的应用。 

一.Scoket 的简介以及和WebServices WCF的区别

1.网络上经常通过程序进行双方的通信,但是在这个过程中,需要进行数据的交换。那么在这个过程中,需要进行建立网络的通讯。

2.通过请求方发出一段报文,给响应方,进行接收,并返回请求报文的结果。

3.所以基于Socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口(经过3次握手),这个就是所谓的Socket编程接口。

4.基于Scoket API 的编程的接口 与WebServices 以及 WebAPI不同的后者都是基于HTTP请求的,但是WCF整合了原有的windows通讯的 .NET Remoting,WebService,Socket的机制,并融合有HTTP 和FTP 的相关技术。进行面向数据通信的程序框架。

5.Socket是面向客户以及服务器模型而设计。 

二:Scoket 的综合的应用

1.Scoket流程图

2.首先请求方进行发送一段报文。

1 
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
请求的报文

3.响应方返回的报文的格式

FT1_IN01
0000
成功
COMPLETE
150
积分查询
1466155364977
2016-06-17 17:22:44.976
05170000000001
0324
1
20160617
001
Reply to responseQ - IBM.SERVICE.RESPONSE.OUT.AFA: FT1_IN01
2016-06-17 09:22:45.327
01
6224520110000004232
0000
成功
101.0
101.0
0.0
响应的报文

三.通过序列化以及反序列化进行解析报文

1.响应的报文的序列化类

1  [Serializable] 2     public class ScoreDetailResponse : ApiResponse 3     { 4         ///  5         /// 结果代码 6         ///  7         public string result_code { get;set; } 8  9         /// 10         /// 结果说明11         /// 12         public string result_info { get;set; }13 14         /// 15         /// 交易日期16         /// 17         public string tran_date { get;set; }18 19         /// 20         /// 交易时间21         /// 22         public string tran_timestamp { get;set; }23 24          /// 25          ///交易积分数26          /// 27          public string transfer_score { get;set; }28          29          /// 30          /// 剩余积分数31          /// 32          public string surplus_score { get;set; }33          34          /// 35          /// 备注36          /// 37          public string remark { get;set; }38 39 40     }41     [Serializable]42     [XmlRoot("Service")]43     public class MyScoreDetailResponse44     {45         public List
_ScoreDetailResponse = new List
();46 [XmlArray("Service_Body")]47 [XmlArrayItem("response")]48 public List
ScoreDetailResponse { get;set; }49 }
Serializable 类

2.序列化继承的接口和方法

1 [XmlRoot("Service")]  2     public  class ApiResponse  3     {  4         [XmlElement("errCode")]  5         public string ErrCode;  6   7         [XmlElement("errMsg")]  8         public string ErrMsg;  9  10         public string Body { get; set; } 11     } 12  13  14    [XmlRoot("IFReturn")] 15         public class IApiRequest { } 16         [XmlRoot("IFReturn")] 17         public class ApiRequest
: IApiRequest where T : ApiResponse 18 { 19 [XmlElement("channel_type")] 20 public string channel_type { get; set; } 21 22 [XmlElement("shop_id")] 23 public string shop_id { get; set; } 24 25 [XmlElement("post_id")] 26 public string post_id { get; set; } 27 } 28 29 30 public interface IParser 31 { 32 ///
33 /// 把响应字符串解释成相应的领域对象。 34 /// 35 ///
领域对象
36 ///
响应字符串 37 ///
领域对象
38 T XMLParse
(string body) where T : ApiResponse; 39 40 ///
41 /// 将对象转换为XML 42 /// 43 ///
44 ///
45 ///
46 string Parse
(T body) where T : IApiRequest; 47 } 48 49 50 51 public class XmlParse:IParser 52 { 53 #region Field 54 private static readonly Regex regex = new Regex("<(\\w+?)[ >]", RegexOptions.Compiled); 55 private static readonly ReaderWriterLock rwLock = new ReaderWriterLock(); 56 private static readonly Dictionary
parsers = new Dictionary
(); 57 #endregion 58 59 #region Members 60 ///
61 /// 将XML转换为对象 62 /// 63 ///
64 ///
65 ///
66 public T ParseDeserialize
(string body) where T : ApiResponse 67 { 68 Type type = typeof(T); 69 string rootTagName = GetRootElement(body); 70 71 string key = type.FullName; 72 if (Constants.ERROR_RESPONSE.Equals(rootTagName)) 73 { 74 key += ("_" + Constants.ERROR_RESPONSE); 75 } 76 77 XmlSerializer serializer = null; 78 bool incl = false; 79 80 rwLock.AcquireReaderLock(50); 81 try 82 { 83 if (rwLock.IsReaderLockHeld) 84 { 85 incl = parsers.TryGetValue(key, out serializer); 86 } 87 } 88 finally 89 { 90 if (rwLock.IsReaderLockHeld) 91 { 92 rwLock.ReleaseReaderLock(); 93 } 94 } 95 96 if (!incl || serializer == null) 97 { 98 XmlAttributes rootAttrs = new XmlAttributes(); 99 rootAttrs.XmlRoot = new XmlRootAttribute(rootTagName);100 101 XmlAttributeOverrides attrOvrs = new XmlAttributeOverrides();102 attrOvrs.Add(type, rootAttrs);103 104 serializer = new XmlSerializer(type, attrOvrs);105 106 rwLock.AcquireWriterLock(50);107 try108 {109 if (rwLock.IsWriterLockHeld)110 {111 parsers[key] = serializer;112 }113 }114 finally115 {116 if (rwLock.IsWriterLockHeld)117 {118 rwLock.ReleaseWriterLock();119 }120 }121 }122 object obj = null;123 using (System.IO.Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(body)))124 {125 obj = serializer.Deserialize(stream);126 }127 128 T rsp = (T)obj;129 if (rsp != null)130 {131 rsp.Body = body;132 }133 return rsp;134 }135 136 ///
137 /// 将对象转换为XML138 /// 139 ///
140 ///
141 ///
142 public string Parse
(T obj) where T : IApiRequest143 {144 XmlSerializer serializer = null;145 146 serializer = new XmlSerializer(obj.GetType());147 XmlSerializerNamespaces xmlns = new XmlSerializerNamespaces();148 xmlns.Add("", "");149 150 string xml = null;151 using (MemoryStream stream = new MemoryStream())152 {153 serializer.Serialize(stream, obj, xmlns);154 xml = Encoding.UTF8.GetString(stream.ToArray());155 }156 157 return xml;158 }159 #endregion160 161 ///
162 /// 获取XML响应的根节点名称163 /// 164 private string GetRootElement(string body)165 {166 Match match = regex.Match(body);167 if (match.Success)168 {169 return match.Groups[1].ToString();170 }171 else172 {173 throw new Exception("Invalid XML response format!");174 }175 }176 177 public T XMLParse
(string body) where T : ApiResponse178 {179 throw new NotImplementedException();180 }181 182 183 ///
184 /// 将XML文件进行反序列话进行对象185 /// 186 ///
结果对象类型
187 ///
包含对象的XML字符串188 ///
编码方式189 ///
反序列化得到的对象
190 public T XmlDeserialize
(string s)191 {192 if (string.IsNullOrEmpty(s))193 {194 throw new ArgumentNullException("s");195 }196 XmlSerializer mySerializer = new XmlSerializer(typeof(T));197 using (MemoryStream ms = new MemoryStream(Encoding.GetEncoding("utf-8").GetBytes(s)))198 {199 using (StreamReader sr = new StreamReader(ms, Encoding.GetEncoding("utf-8")))200 {201 return (T)mySerializer.Deserialize(sr);202 }203 }204 }205 206 }207 208 209 public sealed class Constants210 {211 public const string DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";212 213 public const string SIGN_METHOD_MD5 = "md5";214 215 public const string ACCEPT_ENCODING = "Accept-Encoding";216 public const string CONTENT_ENCODING = "Content-Encoding";217 public const string CONTENT_ENCODING_GZIP = "gzip";218 219 public const string ERROR_RESPONSE = "error_response";220 public const string ERROR_CODE = "code";221 public const string ERROR_MSG = "msg";222 }
反序列化进行解析代码

3.通过控制台应用进行调用

1  #region 获取TCPClient 返回的结果 2         ///  3         /// 获取TCPClient 返回的结果 4         ///  5         ///  6         /// 服务器交易码 7         /// 
8 private string GetTcpClientResult(MemoryStream s, string trans_id) 9 {10 byte[] bufTemp = s.ToArray();11 string xmlContent = bufTemp.Length.ToString().PadLeft(10, '0') + "xxxx" + trans_id + Encoding.GetEncoding("GBK").GetString(bufTemp);12 byte[] buf = Encoding.GetEncoding("GBK").GetBytes(xmlContent);13 string svrAddr = Properties.Settings.Default.TCP_IP;//对方服务器的IP14 int svrPort = Properties.Settings.Default.TCP_PORT;//请求的服务器的端口15 16 using (TcpClient tcpClient = new TcpClient(svrAddr, svrPort))17 {18 var tcpStream = tcpClient.GetStream();19 tcpStream.Write(buf, 0, buf.Length);20 byte[] recv = new byte[4096];21 int recvLen = tcpStream.Read(recv, 0, recv.Length);22 string result = Encoding.GetEncoding("GBK").GetString(recv, 0, recvLen);23 tcpClient.Close();24 return result;25 }26 }27 #endregion
TcpClient 应用Scoket进行发送请求

 

四:整个Scoket 请求处理响应的流程图

 

以上内容全部原创,如需转载,请标明,谢谢!

 

 

转载于:https://www.cnblogs.com/LowKeyCXY/p/6128863.html

你可能感兴趣的文章
8封装的意义和拓展性
查看>>
leetcode15
查看>>
c# Path.Combine
查看>>
noip 2015 子串
查看>>
Windows 窗体控件中的多线程处理之:如何对 Windows 窗体控件进行线程安全调用...
查看>>
C#逐行读取文本文件
查看>>
PHp 密码验证
查看>>
sql 的join
查看>>
世界虽大,但没有破不了的wifi
查看>>
计算机网络中的TCP/IP协议与OSI模型
查看>>
[Javascript] Log Levels and Semantic Methods
查看>>
oo第四次作业
查看>>
UVa 10346 - Peter's Smokes
查看>>
Apache Axis2/C SSL证书验证安全绕过漏洞
查看>>
chrome表单自动填充去掉input黄色背景
查看>>
js数组和字符串
查看>>
[Powershell / VBA] 把excel中的表分离成独立的excel文件
查看>>
kotlin中使用Handler
查看>>
使用hex6x 进行十六进制转换
查看>>
第一章 用标准I/O函数将标准输入复制到标准输出 1-3
查看>>