从第一次写GPS的服务端到现在,已经过去了八年时光。一直是用.net修修改改,从自己写的socket服务,到suppersocket,都是勉强在坚持着,没有真正的稳定过。

  最近一段时间,服务端又出了两个问题:

  1、UDP服务:System.Net.Sockets.SocketException (0x80004005): 当该操作在进行中,由于保持活动的操作检测到一个故障,该连接中断。

  2、数据库操作:System.Data.SqlClient.SqlException (0x80131904): 事务(进程 ID 54)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。

  第一点估计真的是.net socket框架的问题,尝试过网上搜索的解决方案都没有解决,同样的程序在另外一台服务器正常,唯独其中一台隔三差五的就出现这个问题 。以下是服务端部分代码:

      /// <summary>
/// 初始化监听
/// </summary>
private void InitServer()
{
server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
uint IOC_IN = 0x80000000;
uint IOC_VENDOR = 0x18000000;
uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | ;
server.IOControl((int)SIO_UDP_CONNRESET, new Byte[] { Convert.ToByte(false) }, null);//不知道这句有没有用。
string hostName = Dns.GetHostName(); //获取本机名
IPHostEntry localhost = Dns.GetHostEntry(hostName);
IPAddress[] ips = localhost.AddressList;
IPAddress localaddr = null;
foreach (IPAddress ip in ips)
{
if (ip.IsIPv6LinkLocal || ip.IsIPv6Teredo)
{
continue;
}
localaddr = ip;
} state = new State(server);
server.Bind(new IPEndPoint(localaddr, _config.Port));
server.BeginReceiveFrom(state.Buffer, , state.Buffer.Length, SocketFlags.None, ref state.RemoteEP, new AsyncCallback(ReceiveCallBack), state);
}
   private void ReceiveCallBack(IAsyncResult ar)
{
try
{
State _state = ar.AsyncState as State;
int size = server.EndReceiveFrom(ar, ref _state.RemoteEP);
if (size > )
{
byte[] data = new byte[size];
Array.Copy(_state.Buffer, , data, , size);
var session = AddClient(_state.RemoteEP, data);
if (session != null)
{
_state.Session = session;
}
OnReceived?.Invoke(_state.Session, data);
server.BeginReceiveFrom(_state.Buffer, , _state.Buffer.Length, , ref _state.RemoteEP, new AsyncCallback(ReceiveCallBack), _state);
}
else
{
LogHelper.Error("size<=0");
_state = ar.AsyncState as State;
server.BeginReceiveFrom(_state.Buffer, , _state.Buffer.Length, SocketFlags.None, ref _state.RemoteEP, new AsyncCallback(ReceiveCallBack), _state);
//Dispose();
//SessionClosed?.Invoke(_state.Session);
}
}
catch (SocketException ex)
{
LogHelper.Error(ex.ToString());//此处报错
try
{
Dispose();
InitServer();
}
catch (Exception e)
{
LogHelper.Error($"重启时报错{e.ToString()}");
}
}
}

  而第二点数据库的操作,则是设计缺陷了,四个端口接收不同协议的终端数据,定时5秒批量写入历史数据表和批量update一张最新数据的表,这张最新数据表还有前端在定时select。

  时不时的深更半夜接到客户电话要求处理,也是心累了,因此,想尝试一下用golang+MQ+.net的解决方案,试图彻底解决以上烦恼。成功与否那是后话,先要有所尝试嘛。

  架构图:

  这种设计可能存在的风险:Socket Server写入MQ Server的速度如果大于MQ Clients到SqlServer的速度,会导致数据延时,最主要服务器内存受不了。系统需求又不允许MQ消费者丢弃任何数据。

  没关系,我们先假设处理速度能快于接收速度,否则生活没法继续,哈哈。

  先上一段golang服务端代码

package main

import (
"fmt"
"net"
"time"
"configmanager"
"logger"
)
func checkError(err error){
if err != nil {
fmt.Println(err)
}
}
func clientHandle(conn *net.UDPConn) {
var buf []byte
size, addr, err := conn.ReadFromUDP(buf[:])
if err != nil {
logger.Error.Println(err)
return
} daytime :=time.Now().Format("2006-01-02 15:04:05");
var buff =buf[:size]
logger.Info.Printf("%x\r\n",buff)//此处先打印,下篇写入MQ
conn.WriteToUDP([]byte(daytime), addr)
}
func main(){
configmanager.Initialize()//初始化配置文件处理包,将配置config.ini写入到全局映射AppSettings中
port := configmanager.AppSettings["port"]
logger.Info.Print("开始在" + port + "监听\r\n")
udpaddr,err:=net.ResolveUDPAddr("udp4",":" + port)
checkError(err)
udpconn,err := net.ListenUDP("udp",udpaddr)
checkError(err)
for{
clientHandle(udpconn);
}
}

打开编译后的应用程序,同时打开TcpUdp压测工具

以上,golang的UDP服务端就成功了,下一篇再要看看golang是怎么操作rabbitmq的

GPS服务端(上)-Socket服务端(golang)的更多相关文章

  1. 记一次阿里云oss文件上传服务假死

    引言 记得以前刚开始学习web项目的时候,经常涉及到需要上传图片啥的,那时候都是把图片上传到当前项目文件夹下面,每次项目一重启图片就丢了.虽然可以通过修改/tomcat/conf/server.xml ...

  2. Chris Richardson微服务翻译:微服务架构中的服务发现

    Chris Richardson 微服务系列翻译全7篇链接: 微服务介绍 构建微服务之使用API网关 构建微服务之微服务架构的进程通讯 微服务架构中的服务发现(本文) 微服务之事件驱动的数据管理 微服 ...

  3. MSDN上的异步socket 服务端例子

    MSDN上的异步socket 服务端例子 2006-11-22 17:12:01|  分类: 代码学习 |  标签: |字号大中小 订阅     Imports SystemImports Syste ...

  4. C# TCP socket发送大数据包时,接收端和发送端数据不一致 服务端接收Receive不完全

    简单的c# TCP通讯(TcpListener) C# 的TCP Socket (同步方式) C# 的TCP Socket (异步方式) C# 的tcp Socket设置自定义超时时间 C# TCP ...

  5. 在python中编写socket服务端模块(二):使用poll或epoll

    在linux上编写socket服务端程序一般可以用select.poll.epoll三种方式,本文主要介绍使用poll和epoll编写socket服务端模块. 使用poll方式的服务器端程序代码: i ...

  6. AutoCAD.net支持后台线程-Socket服务端

    最近因为公司项目的需求,CAD作为服务端在服务器中常驻运行,等待客户端远程发送执行任务的指令,最终确认用Socket-tcp通讯,CAD需要实时监听客户端发送的消息,这时就需要开启线程执行Socket ...

  7. 基于netty的socket服务端触发了channelInactive方法,但实际连接没有断开的问题

    背景: 一个中小型H5游戏,后端使用基于 netty 的socket服务 服务端 分为 分发服务器 & 业务服务器,业务服务器可负载 用户客户端与分发服务器连接 分发服务器再作为客户端与每台业 ...

  8. TCP客户端图片上传服务端保存本地示例

    //TCP客户端public class TCPClient { public static void main(String[] args)throws IOException { Socket s ...

  9. 关于调试php的socket服务端中遇到的问题及解决办法

    今天终于把socket的服务端解决了,期间遇到了很多问题呢~ 1.用cmd运行php的问题: 2.socket_create()函数未定义问题: 3.查看端口的问题. 以下逐一说说解决办法: 1.在c ...

随机推荐

  1. Android中Activity被系统会收前页面信息保存

    1.重写onSaveInstanceState方法 protected void onSaveInstanceState(Bundle outState) { super.onSaveInstance ...

  2. mac 系统安装 eclipse 方法

    经过好几天的折腾,终于在各种不靠谱的经验.说明的忽悠中把自己心爱的 mac 安装上了 eclipse,看到别人的不靠谱,我决定自己写一篇经验,为了大家能够不走我这么多的弯路,也为了自己将来可以回来看看 ...

  3. spring+mybatis+c3p0数据库连接池或druid连接池使用配置整理

    在系统性能优化的时候,或者说在进行代码开发的时候,多数人应该都知道一个很基本的原则,那就是保证功能正常良好的情况下,要尽量减少对数据库的操作. 据我所知,原因大概有这样两个: 一个是,一般情况下系统服 ...

  4. 嵌入式Linux引导过程之1.6——Xloader的Xloader_Entry

    我们已经看完了XLOADER_ENTRY里调用的前两个标号的代码,分别是sys_init和ddr_init.对于一个嵌入式系统来说,这两 个部分的代码是在一开始就执行的,至少是在从bootrom里面的 ...

  5. List转换成JSON对象报错(五)

    List转换成JSON对象 1.具体错误如下 Exception in thread "main" java.lang.NoClassDefFoundError: org/apac ...

  6. freemarker中的split字符串分割

    freemarker中的split字符串分割 1.简易说明 split分割:用来根据另外一个字符串的出现将原字符串分割成字符串序列 2.举例说明 <#--freemarker中的split字符串 ...

  7. Java获取某年某季度的第一天出错

    1.错误描述 Exception in thread "main" java.lang.IllegalArgumentException: Cannot format given ...

  8. RAPIDIO高速串行协议

    RapidIO是由Motorola和Mercury等公司率先倡导的一种高性能. 低引脚数. 基于数据包交换的互连体系结构,是为满足和未来高性能嵌入式系统需求而设计的一种开放式互连技术标准.RapidI ...

  9. SDP(10):文本式大数据运算环境-MongoDB-Engine功能设计

    为了让前面规划的互联网+数据平台能有效对电子商务数据进行管理及实现大数据统计功能,必须在平台上再增加一个MongDB-Engine:数据平台用户通过传入一种Context来指示MongoDB-Engi ...

  10. Halcon的应用程序 打开后 弹出没有帮助文件错误提示

    问题: Halcon的应用程序 打开后 弹出没有帮助文件错误提示 解决方法: 建立(C:\ProgramFiles\MVTec\halcon)目录,将halcon安装目录下的help文件夹复制过来即可 ...