douyu danmu test c#
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading; namespace danmu
{
class Program
{
private static string SERVER_DOMAIN = "openbarrage.douyutv.com";
private static int SERVER_PORT = 8601;
private static int ROOM_ID = 288016;
private static string FIX_TAIL = String.Empty; //拼接处理后被丢弃的数据,防止弹幕丢失
class BrrageMsg
{
public string Name = String.Empty;
public string Txt = String.Empty;
}
static void Main(string[] args)
{
try
{
Socket tcpClient = InitTcp(SERVER_DOMAIN, SERVER_PORT);
Thread getDanmuThread = new Thread(GetDanmu);
getDanmuThread.Start(tcpClient);
Thread keepAliveThread = new Thread(KeepAlive);
keepAliveThread.Start(tcpClient);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
} static Socket InitTcp(string host, int port)
{
IPHostEntry hostInfo = Dns.GetHostEntry(host);
IPAddress ipAddress = hostInfo.AddressList[0]; //域名转IP
IPEndPoint ipe = new IPEndPoint(ipAddress, port);
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
s.Connect(ipe);
return s;
}
static byte[] DataToBytes(string data)
{
string dantaNew = data + "\0";
byte[] bodyDataByte = Encoding.UTF8.GetBytes(dantaNew);
byte[] cType = BitConverter.GetBytes(689); int dataLength = dantaNew.Length + cType.Length + 8;
byte[] dataLengthByte = BitConverter.GetBytes(dataLength);
byte[] dataLengthByte2 = BitConverter.GetBytes(dataLength);
byte[] result = new byte[dataLength + 4]; Array.Copy(dataLengthByte, 0, result, 0, 4);
Array.Copy(dataLengthByte2, 0, result, 4, 4);
Array.Copy(cType, 0, result, 8, 4);
Array.Copy(bodyDataByte, 0, result, 12, bodyDataByte.Length);
byte[] source = new byte[result.Length];
Array.Copy(result, 0, source, 0, result.Length);
return result;
} static void GetDanmu(object obj)
{
Socket tcpClient = (Socket)obj;
string login = "type@=loginreq/roomid@=" + ROOM_ID + "/";
byte[] loginBytes = DataToBytes(login);
tcpClient.Send(loginBytes);
string joingroup = "type@=joingroup/rid@=" + ROOM_ID + "/gid@=-9999/";
byte[] joingroupBytes = DataToBytes(joingroup);
tcpClient.Send(joingroupBytes);
string recvStr = "";
byte[] recvBytes = new byte[1024];
int bytes;
while (true)
{
bytes = tcpClient.Receive(recvBytes, recvBytes.Length, 0);//从服务器端接受返回信息
recvStr = Encoding.UTF8.GetString(recvBytes, 0, bytes);
ShowMsg(recvStr);
}
} static BrrageMsg GetMsgType(string[] msgType)
{
BrrageMsg brrageMsg = new BrrageMsg();
foreach (string keyValueTemp in msgType)
{
string[] keyValue = Regex.Split(keyValueTemp, "@=", RegexOptions.IgnoreCase);
if (keyValue.Length >= 2)
{
string key = keyValue[0];
string[] textArr = new string[keyValue.Length - 1];
Array.Copy(keyValue, 1, textArr, 0, keyValue.Length - 1);
string value = String.Join("@", textArr);
if (key == "nn")
{
brrageMsg.Name = value;
}
if ((key == "txt"))
{
brrageMsg.Txt = value;
}
}
}
return brrageMsg;
}
static void ShowMsg(string msg)
{
msg = FIX_TAIL + msg;
string[] chatmsgArray = Regex.Split(msg, "type@=", RegexOptions.IgnoreCase);
FIX_TAIL = chatmsgArray[chatmsgArray.Length - 1]; //截取最后的丢弃数据,放在下个包的开头,防止数据丢失
string[] newChatmsgArrayArr = new string[chatmsgArray.Length - 1];
Array.Copy(chatmsgArray, 0, newChatmsgArrayArr, 0, chatmsgArray.Length - 1); foreach (string t in newChatmsgArrayArr)
{
string[] msgType = t.Split('/');
if (msgType.Length >= 2)
{
string type = msgType[0];
if (type == "chatmsg")
{
BrrageMsg brrageMsg = GetMsgType(msgType);
string result = String.Format("[{0}]: {1}", brrageMsg.Name, brrageMsg.Txt);
Console.WriteLine(result +" "+ DateTime.Now );
}
}
}
}
static void KeepAlive(object obj)
{
Socket tcpClient = (Socket)obj;
byte[] aliveMsg = DataToBytes("type@=mrkl/");
while (true)
{
tcpClient.Send(aliveMsg);
Thread.Sleep(40000);
}
}
}
}
2: another - (not test)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace C1
{
class Program
{
public static string RoomID;
static void Main(string[] args)
{
Console.Title = "斗鱼弹幕小助手";
Console.ForegroundColor = ConsoleColor.Gray;
// 设定服务器IP地址
IPAddress ip = IPAddress.Parse("115.231.96.19");
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
clientSocket.Connect(new IPEndPoint(ip, 12604)); //配置服务器IP与端口
Console.WriteLine("连接服务器成功");
Console.WriteLine("请输入房间ID号");
RoomID = Console.ReadLine(); string send = "type@=loginreq/username@=visitor1687994/password@=1234567890123456/roomid@=" + RoomID + "/dfl@=sn@AA=105@ASss@AA=1/ct@=0/ver@=20180413/aver@=2018051611/";
MsgBody sBody = new MsgBody(send);
clientSocket.Send(sBody.ToByteArray());
Console.WriteLine("向服务器发送消息:{0}" + send);
}
catch (Exception e)
{
Console.WriteLine("连接服务器失败,请按回车键退出!");
return;
}
//通过clientSocket接收数据 Thread receiveThread = new Thread(reMsg);
receiveThread.Start(clientSocket);
Thread receiveThread2 = new Thread(SendMsg);
receiveThread2.Start(clientSocket);
Console.ReadLine();
}
/// <summary>
/// 取中间值
/// </summary>
/// <param name="allStr"></param>
/// <param name="firstStr"></param>
/// <param name="lastStr"></param>
/// <returns></returns>
public static string GetStringMid(string allStr, string firstStr, string lastStr)
{
try
{
int index1 = allStr.IndexOf(firstStr);
int index2 = allStr.IndexOf(lastStr, index1 + firstStr.Length); if (index1 < 0 || index2 < 0)
{
return "";
} index1 = index1 + firstStr.Length;
index2 = index2 - index1; if (index1 < 0 || index2 < 0)
{
return "";
}
return allStr.Substring(index1, index2);
}
catch (Exception ex)
{ throw;
}
} static void reMsg(object socket)
{
byte[] saveArr = new byte[0];
byte[] result = new byte[1024];
while (true)
{
try
{
int receiveLength = ((Socket)socket).Receive(result);
if (receiveLength > 0)
{
if (saveArr.Length > 0)
{
byte[] arr = new byte[saveArr.Length + receiveLength];
Array.Copy(saveArr, 0, arr, 0, saveArr.Length);
Array.Copy(result, 0, arr, saveArr.Length, receiveLength);
result = arr;
receiveLength = result.Length;
}
int head = 0;
if (result.Length < 4)
{
saveArr = new byte[receiveLength];
Array.Copy(result, 0, saveArr, 0, saveArr.Length);
continue;
}
head = BitConverter.ToInt32(SubByte(result, 0, 4), 0); string str = string.Empty;
if (head > (receiveLength - 4))
{
saveArr = new byte[result.Length];
Array.Copy(result, 0, saveArr, 0, saveArr.Length);
continue;
}
int index = 0;
do
{
MsgBody reBodyMsg = new MsgBody(result.Take(head + 4).ToArray());
str = reBodyMsg.BodyData;
index = head + 4;
if (str.IndexOf("keeplive") != -1)
{
//心跳
}
else if (str.IndexOf("type@=chatmsg") != -1)
{
string txt = GetStringMid(str, "txt@=", "/");
string name = "[" + GetStringMid(str, "nn@=", "/") + "]"; //name = name.PadRight(15);
name = name + new string(' ', 30 - Encoding.Default.GetByteCount(name));
name = string.Format("{0}发送弹幕", name);
name = name + new string(' ', 50 - Encoding.Default.GetByteCount(name));
Console.WriteLine(name + txt); }
else if (str.IndexOf("type@=uenter") != -1)
{
str = "欢迎[" + GetStringMid(str, "nn@=", "/") + "]"; str = str + new string(' ', 30 - Encoding.Default.GetByteCount(str)); Console.WriteLine("{0}进入直播间", str);
}
else if (str.IndexOf("loginres") != -1)
{
string send = "type@=joingroup/rid@=" + RoomID + "/gid@=-9999/";
MsgBody sBody = new MsgBody(send);
((Socket)socket).Send(sBody.ToByteArray());
}
else
{
// Console.WriteLine("接收服务器消息:{0}", str);
}
if (index < receiveLength)
{
try
{
result = SubByte(result, index, receiveLength - index);
if (result.Length <= 12)
{
saveArr = new byte[result.Length];
Array.Copy(result, 0, saveArr, 0, saveArr.Length);
break;
}
head = BitConverter.ToInt32(SubByte(result, 0, 4), 0);
if (result.Length < (head + 4))
{
saveArr = new byte[result.Length];
Array.Copy(result, 0, saveArr, 0, saveArr.Length);
break;
}
receiveLength = result.Length;
continue;
}
catch (Exception ex)
{ throw;
}
}
saveArr = new byte[0];
break;
} while (true); } }
catch (Exception ex)
{ throw;
}
}
} /// <summary>
/// 心跳
/// </summary>
/// <param name="socket"></param>
static void SendMsg(object socket)
{
Socket sk = (Socket)socket;
while (true)
{
//
byte[] b = new byte[] { 0x54, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0xB1, 0x02, 0x00, 0x00 };
List<byte> sendData = new List<byte>(b);
sendData.AddRange(Encoding.UTF8.GetBytes("type@=keeplive/tick@=" + GetCurrentTimeUnix() + "/vbw@=0/k@=23d36a0db24136aabee566e0aa748344/"));
sendData.Add(0x00);
sk.Send(sendData.ToArray());
Thread.Sleep(15000);
}
} /// <summary>
/// 获取当前本地时间戳
/// </summary>
/// <returns></returns>
public static long GetCurrentTimeUnix()
{
TimeSpan cha = (DateTime.Now - TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)));
long t = (long)cha.TotalSeconds;
return t;
}
/// <summary>
/// 字符串MD5
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static string md5(string input)
{
//chenwancheng0true1
byte[] buffer = MD5.Create().ComputeHash(Encoding.GetEncoding("ISO-8859-1").GetBytes(input));
return binl2hex(buffer);
} public static string binl2hex(byte[] buffer)
{
StringBuilder builder = new StringBuilder();
for (int i = 0; i < buffer.Length; i++)
{
builder.Append(buffer[i].ToString("x2"));
}
return builder.ToString().ToLower();
}
/// <summary>
/// 截取字节数组
/// </summary>
/// <param name="srcBytes">要截取的字节数组</param>
/// <param name="startIndex">开始截取位置的索引</param>
/// <param name="length">要截取的字节长度</param>
/// <returns>截取后的字节数组</returns>
public static byte[] SubByte(byte[] srcBytes, int startIndex, int length)
{
System.IO.MemoryStream bufferStream = new System.IO.MemoryStream();
byte[] returnByte = new byte[] { };
if (srcBytes == null) { return returnByte; }
if (startIndex < 0) { startIndex = 0; }
if (startIndex < srcBytes.Length)
{
if (length < 1 || length > srcBytes.Length - startIndex) { length = srcBytes.Length - startIndex; }
bufferStream.Write(srcBytes, startIndex, length);
returnByte = bufferStream.ToArray();
bufferStream.SetLength(0);
bufferStream.Position = 0;
}
bufferStream.Close();
bufferStream.Dispose();
return returnByte;
} }
} using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace C1
{
public class MsgBody
{
public MsgBody()
{ }
public MsgBody(string str)
{
this.BodyData = str;
ToByteArray();
}
public MsgBody(byte[] b)
{
this.Source = b;
SetValues();
}
public int DataLength;
public byte[] DataLength_Byte; public int DataLength_2;
public byte[] DataLength_2_Byte; public int Cmd = 689;
public byte[] Cmd_Byte; public string BodyData;
public byte[] BodyData_Byte; public byte End = 0; public byte[] Source; public byte[] ToByteArray()
{
BodyData_Byte = Encoding.UTF8.GetBytes(BodyData);
Cmd_Byte = BitConverter.GetBytes(Cmd);
DataLength = DataLength_2 = BodyData_Byte.Length + Cmd_Byte.Length + 4 + 1;
DataLength_Byte = BitConverter.GetBytes(DataLength);
DataLength_2_Byte = BitConverter.GetBytes(DataLength_2); byte[] result = new byte[DataLength + 4];
Array.Copy(DataLength_Byte, 0, result, 0, 4);
Array.Copy(DataLength_2_Byte, 0, result, 4, 4);
Array.Copy(Cmd_Byte, 0, result, 8, 4);
Array.Copy(BodyData_Byte, 0, result, 12, BodyData_Byte.Length);
Source = new byte[result.Length];
Array.Copy(result, 0, Source, 0, result.Length);
return result;
} public void SetValues()
{
try
{
DataLength_Byte = Program.SubByte(Source, 0, 4);
DataLength_2_Byte = Program.SubByte(Source, 4, 4);
Cmd_Byte = Program.SubByte(Source, 8, 4);
BodyData_Byte = Program.SubByte(Source, 12, Source.Length - 13);
End = Program.SubByte(Source, Source.Length - 2, 1)[0]; DataLength = BitConverter.ToInt32(DataLength_Byte, 0);
DataLength_2 = BitConverter.ToInt32(DataLength_2_Byte, 0);
Cmd = BitConverter.ToInt32(Cmd_Byte, 0);
BodyData = Encoding.UTF8.GetString(BodyData_Byte);
}
catch (Exception ex)
{ throw;
}
}
}
}
douyu danmu test c#的更多相关文章
- 第8月第12天 python json.dumps danmu
1.json.dumps return JsonResponse({ 'status': WechatMessage.POST_METHOD_REQUIRED[1], 'status_code': W ...
- 发现一个名为“Douyu”的国人项目
刚刚在javaeye看到一个名为Douyu的国人项目,认为搞下去未来可能非常有意思,放到blog上做个标记. ——————下面是转载的作者原文——————— 原文地址例如以下:http://zhh20 ...
- 每个大主播都是满屏弹幕,怎么做到的?Python实战无限刷弹幕!
anmu 是一个开源的直播平台弹幕接口,使用他没什么基础的你也可以轻松的操作各平台弹幕.使用不到三十行代码,你就可以使用Python基于弹幕进一步开发.支持斗鱼.熊猫.战旗.全民.Bilibili多平 ...
- 推荐Android几个优质的完整项目学习
==>来自于微信公众号==鸿洋.大家可以关注一波大神之作. 后台经常有人问我能不能推荐几个完整项目用于学习.借着周末的机会,给大家推荐几个,项目我基本都在本地运行过,并且会在文章末尾提供每个项目 ...
- 第一个chrome extension
如今,chrome浏览器的使用如越来越流行,chrome extension往往能提供更多很丰富的功能.以前一直想了解这方面的东西,可是又担心很复杂.前段时间,在斗鱼看一个直播,想刷弹幕,但是每次自己 ...
- jQuery+css3 弹幕
写了个基于jQuery+css3的弹幕功能,此功能面向手机wap,利用改变位移做弹幕功能会使一些性能低的手机浏览器卡,所以用了css3,此功能不支持非webkit内核浏览器 html部分 自己设置样式 ...
- Ajax省市区无刷新单表联动查询
方法一: 在很多时候都需要用到无刷新级联查询,本文将以省市区的级联查询作为例子.注:此为单表三级联动 环境:Vistual Studio 2015 .MSSQL 1.首先下载AjaxControlTo ...
- git和nginx安装
原始地址: https://www.zybuluo.com/freeethy/note/192109 git安装 设置git的username和email (注册gitlab的账号密码) $$ git ...
- 使用swoole和websocket结合来制造弹幕
在知乎上无意中看到了一篇有关这个的话题https://zhuanlan.zhihu.com/p/23992890,刚好没事也好久没弄swoole了就自己按照知乎上的那篇文站实操了一下 那个试验中有几个 ...
随机推荐
- 可以提升幸福感的js小技巧(下)
4.数字 4.1 不同进制表示法 ES6中新增了不同进制的书写格式,在后台传参的时候要注意这一点. 29 // 10进制 035 // 8进制29 原来的方式 0o35 // 8进制29 ES6的方式 ...
- 推荐JavaScript动态效果库
翻译:疯狂的技术宅,原文:https://blog.bitsrc.io/11-javascript-animation-libraries-for-2018-9d7ac93a2c59 当我想要在网上找 ...
- java获取json数组格式中的值
第一种方法: String str = "{'array':[{'id':5,'name':'张三'},{'id':6,'name':'李四'}]}"; JSONArray jso ...
- 2019-11-29-git-需要知道的1000个问题
title author date CreateTime categories git 需要知道的1000个问题 lindexi 2019-11-29 8:36:7 +0800 2018-2-13 1 ...
- SQL的基本操作(三)
Hive基本SQL操作 Hive DDL(数据库定义语言) 1.数据库的基本操作 --展示所有数据库 show databases; --切换数据库 use database_name; /*创建数据 ...
- 深入理解docker
注意这是一篇笔记整理,来源是一篇公众号,https://mp.weixin.qq.com/s/vS-Dp31T19Rk_tQj2GzmCQ 为了自己更好的查看和理解,涉及到侵权联系删! 目录: Ima ...
- Anaconda3安装及使用
一.安装及环境变量配置 1.从这里下载Anaconda 2.根据提示安装即可 3.配置环境变量:%Anaconda%\Script 打开命令行,输入:conda --version,回显版本即完成安装 ...
- puppet运维自动化之用户管理
系统管理员离不开账户管理,账户管理,密码管理,开发机器,测试机器,线上机器,都需要创建用户,并给与相关用户的权限.你如果要创建100个,1000个账户和密码,你会不会疯掉,如何在1分钟完成百上千个账户 ...
- CSP-S2019游记&拆塔记
不是拆广州塔 Day -inf 四套NOI模拟降智 Day0 拆了一发新新 本来想复习小圆脸结果拆了3h最后还没带任意门 没有帘子可还行 第一天由于没发现被子可以抽出来就没睡好 Day1 8:30开考 ...
- python Tkinter 编程
Tkinter 是 Python 的标准 GUI 库.Python 使用 Tkinter 可以快速的创建 GUI 应用程序. 由于 Tkinter 是内置到 python 的安装包中.只要安装好 Py ...