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 ...
随机推荐
- Django使用模板后无法找到静态资源文件
Django使用模板后无法找到静态资源文件 环境配置 Django版本1.11 python版本3.6.2 前言 在编写Django网站的时候,在涉及模板方面,一些简单的例子都没有问题,但这些例子都有 ...
- javascript form表单常用的正则表达式
form验证时常用的几个正则表达式 座机: \d{3,4}-\d{7,8} 手机号: /^1[34578][0-9]{9}$/ (\86)?\s+1[34578]\d{0-9} (\+86)?\s*1 ...
- Linux XZ压缩格式学习
XZ的介绍 今天升级Python的时候,下载的Python-2.7.8.tar.xz安装包为xz格式,好吧,我又孤陋寡闻了,居然第一次遇见xz格式的压缩文件.搜索了一下资料,下面是xz的一些介绍: ...
- Android Scheme协议与应用全解析
URL Scheme 的作用 客户端应用可以向操作系统注册一个 URL Scheme,该 Scheme 用于从浏览器或其他应用中启动本应用. 通过指定的 URL 字段,可以让应用在被调起后直接打开某些 ...
- Struts2实现文件上传报错(四)
1.具体错误如下 2014-5-2 21:38:29 com.opensymphony.xwork2.util.logging.jdk.JdkLogger error 严重: Exception oc ...
- 你的变量究竟存储在什么地方 && 全局内存
我相信大家都有过这样的经历,在面试过程中,考官通常会给你一道题目,然后问你某个变量存储在什么地方,在内存中是如何存储的等等一系列问题.不仅仅是在面试中,学校里面的考试也会碰到同样的问题. 如果你还不 ...
- arttemplate与webpack的应用
模板渲染使用arttemplate,使用方法如下: 普通使用 普通使用把渲染模板写在<script>标签里面,引入arttemplate.js,从服务端接收数据(数组与对象的形式),然后调 ...
- jenkins部署web项目到webogic
注: Docker容器里安装的jenkins,Docker容易里安装的weblogic 在jenkins里面直接将打包好的 war 包通过 Publish over SSH插件 放入 weblogic ...
- Excel 转 vCard格式、CSV格式
Excel 转vCard格式(常用于Gmail, Yahoo, 163等).CSV格式(常用于Outlook, Foxmail等) 最近公司邮件通讯录需要更新,我就将原来的通讯录给删除了,准备重新导入 ...
- ASP.NET CORE入门之读取Json配置文件
首先新建一.net core控制台项目,命名为jsonReader 然后选中引用,选择NuGet包管理器,点击浏览引入mircosoft.aspnetcore.all并安装 选中解决方案,填加,新建项 ...