GPS服务端(上)-Socket服务端(golang)
从第一次写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)的更多相关文章
- 记一次阿里云oss文件上传服务假死
引言 记得以前刚开始学习web项目的时候,经常涉及到需要上传图片啥的,那时候都是把图片上传到当前项目文件夹下面,每次项目一重启图片就丢了.虽然可以通过修改/tomcat/conf/server.xml ...
- Chris Richardson微服务翻译:微服务架构中的服务发现
Chris Richardson 微服务系列翻译全7篇链接: 微服务介绍 构建微服务之使用API网关 构建微服务之微服务架构的进程通讯 微服务架构中的服务发现(本文) 微服务之事件驱动的数据管理 微服 ...
- MSDN上的异步socket 服务端例子
MSDN上的异步socket 服务端例子 2006-11-22 17:12:01| 分类: 代码学习 | 标签: |字号大中小 订阅 Imports SystemImports Syste ...
- C# TCP socket发送大数据包时,接收端和发送端数据不一致 服务端接收Receive不完全
简单的c# TCP通讯(TcpListener) C# 的TCP Socket (同步方式) C# 的TCP Socket (异步方式) C# 的tcp Socket设置自定义超时时间 C# TCP ...
- 在python中编写socket服务端模块(二):使用poll或epoll
在linux上编写socket服务端程序一般可以用select.poll.epoll三种方式,本文主要介绍使用poll和epoll编写socket服务端模块. 使用poll方式的服务器端程序代码: i ...
- AutoCAD.net支持后台线程-Socket服务端
最近因为公司项目的需求,CAD作为服务端在服务器中常驻运行,等待客户端远程发送执行任务的指令,最终确认用Socket-tcp通讯,CAD需要实时监听客户端发送的消息,这时就需要开启线程执行Socket ...
- 基于netty的socket服务端触发了channelInactive方法,但实际连接没有断开的问题
背景: 一个中小型H5游戏,后端使用基于 netty 的socket服务 服务端 分为 分发服务器 & 业务服务器,业务服务器可负载 用户客户端与分发服务器连接 分发服务器再作为客户端与每台业 ...
- TCP客户端图片上传服务端保存本地示例
//TCP客户端public class TCPClient { public static void main(String[] args)throws IOException { Socket s ...
- 关于调试php的socket服务端中遇到的问题及解决办法
今天终于把socket的服务端解决了,期间遇到了很多问题呢~ 1.用cmd运行php的问题: 2.socket_create()函数未定义问题: 3.查看端口的问题. 以下逐一说说解决办法: 1.在c ...
随机推荐
- jquery源码分析之一前言篇
1.问:jquery源码分析的版本是什么? 答:v3.2.1 2.问:为什么要分析jquery源码? 答:javascript是一切js框架的基础,jquery.es6.vue.angular.rea ...
- 3.2 PCI设备的数据传递
PCI设备的数据传递使用地址译码方式,当一个存储器读写总线事务到达PCI总线时,在这条总线上的所有PCI设备将进行地址译码,如果当前总线事务使用的地址在某个PCI设备的BAR空间中时,该PCI设备将使 ...
- Linux显示以时间生升序显示文件
Linux显示以时间生升序显示文件 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ ls -lnt 总用量 56 -rw-rw-r-- 1 1000 1000 ...
- mkfs -t ext3 错误/dev/sdxx is apparently in use by the system; 解决方法
在存储上共享了一个500G的空间,映射到Linux系统提供上,环境由2个节点组成. 一. 测试一: 直接mount 用fdisk 格式化之后如下: [root@rac1 u01]# fdisk ...
- 浅谈IT企业挑选技术人员招聘几个要点
在实际人员招聘的一些感想总结,企业需要怎么样的人才,个人总结如下: 1.技术能力不是第一位 企业在招聘一个人的时候往往看你第一点不是技术实力,而是你个人言谈行为和态度,往往一个面试你的人员他不可能在半 ...
- sql一张表中两个字段指向同一个外键
在项目开发中遇到这么一个例子,首先产品表 tb_product ----------------------------- id name 1 手机 2 电脑 3 笔记本 ...
- Python 爬取 中关村CPU名字和主频
0.准备工作 1.相关教程 Python 爬虫系列教程:http://cuiqingcai.com/1052.html Python Web课程:http://ww ...
- PyTorch官方中文文档:PyTorch中文文档
PyTorch中文文档 PyTorch是使用GPU和CPU优化的深度学习张量库. 说明 自动求导机制 CUDA语义 扩展PyTorch 多进程最佳实践 序列化语义 Package参考 torch to ...
- Emacs考场配置
当年\(NOip\)考场配置不记得啦 存在这里搞事情 (set-background-color "gray15") (set-foreground-color "gra ...
- 浅谈API安全设计
一.简述 安全是恒久的话题,如果不注意防范,会带来很严重的后果.比如: 1.接口被大规模调用消耗系统资源,影响系统的正常访问,甚至系统瘫痪 2.数据泄露 3.伪造(篡改)数据,制造垃圾数据 4.App ...