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#的更多相关文章

  1. 第8月第12天 python json.dumps danmu

    1.json.dumps return JsonResponse({ 'status': WechatMessage.POST_METHOD_REQUIRED[1], 'status_code': W ...

  2. 发现一个名为“Douyu”的国人项目

    刚刚在javaeye看到一个名为Douyu的国人项目,认为搞下去未来可能非常有意思,放到blog上做个标记. ——————下面是转载的作者原文——————— 原文地址例如以下:http://zhh20 ...

  3. 每个大主播都是满屏弹幕,怎么做到的?Python实战无限刷弹幕!

    anmu 是一个开源的直播平台弹幕接口,使用他没什么基础的你也可以轻松的操作各平台弹幕.使用不到三十行代码,你就可以使用Python基于弹幕进一步开发.支持斗鱼.熊猫.战旗.全民.Bilibili多平 ...

  4. 推荐Android几个优质的完整项目学习

    ==>来自于微信公众号==鸿洋.大家可以关注一波大神之作. 后台经常有人问我能不能推荐几个完整项目用于学习.借着周末的机会,给大家推荐几个,项目我基本都在本地运行过,并且会在文章末尾提供每个项目 ...

  5. 第一个chrome extension

    如今,chrome浏览器的使用如越来越流行,chrome extension往往能提供更多很丰富的功能.以前一直想了解这方面的东西,可是又担心很复杂.前段时间,在斗鱼看一个直播,想刷弹幕,但是每次自己 ...

  6. jQuery+css3 弹幕

    写了个基于jQuery+css3的弹幕功能,此功能面向手机wap,利用改变位移做弹幕功能会使一些性能低的手机浏览器卡,所以用了css3,此功能不支持非webkit内核浏览器 html部分 自己设置样式 ...

  7. Ajax省市区无刷新单表联动查询

    方法一: 在很多时候都需要用到无刷新级联查询,本文将以省市区的级联查询作为例子.注:此为单表三级联动 环境:Vistual Studio 2015 .MSSQL 1.首先下载AjaxControlTo ...

  8. git和nginx安装

    原始地址: https://www.zybuluo.com/freeethy/note/192109 git安装 设置git的username和email (注册gitlab的账号密码) $$ git ...

  9. 使用swoole和websocket结合来制造弹幕

    在知乎上无意中看到了一篇有关这个的话题https://zhuanlan.zhihu.com/p/23992890,刚好没事也好久没弄swoole了就自己按照知乎上的那篇文站实操了一下 那个试验中有几个 ...

随机推荐

  1. 解决jenkins的Console Output中文乱码

    1.本地机器设置环境变量(设置后需要注销计算机才能生效) key: JAVA_TOOL_OPTIONS value:-Dfile.encoding=UTF- 2. 通过Jenkins全局设置的方式   ...

  2. xml的解析及案例的分析和分享

    HTML的文档如下: <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset=& ...

  3. 常用Java中response.setContentType参数

    image/bmp BMP image/png PNG image/gif GIF image/jpeg JPEG image/tiff TIFF image/x-dcx DCX image/x-pc ...

  4. Centos7安装升级Ruby和集群搭建参考

    安装升级Ruby参考:https://blog.csdn.net/qq_26440803/article/details/82717244 集群搭建参考:https://www.cnblogs.com ...

  5. windows server :远程桌面服务当前正忙,因此无法完成您尝试执行的任务

    原因是:Csrss.exe 进程和某些应用程序 (例如,Microsoft Excel 或 Microsoft Visio) 之间发生的死锁情况下会出现此问题. 解决:下载一个修复补丁,安装后重启服务 ...

  6. 22_2mybatis——CURD

    1.CURD操作 第一步:创建maven工程并导入坐标 <?xml version="1.0" encoding="UTF-8"?> <pro ...

  7. java 基本包

    1. import java.io.BufferedInputStream;import java.io.File;import java.io.FileInputStream;import java ...

  8. docker概述和安装

    一:概述 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器或Windows 机器上,也可以实现虚拟化,容器是完全使用 ...

  9. JAVA利用递归的方法删除一个文件夹以及文件夹下所有的子文件

    public static boolean deleteFolder(String url) { File file = new File(url); if (!file.exists()) { re ...

  10. 曝郭盛华公司30万美元收购Acn.ai域名,揭秘人工智能布局下的巨头们

    据域名投资人曝料,郭盛华公司已经提前拿下.ai短域名 Acn.ai,目前域名已经设置跳转到东联科技的官网.都说域名越短越值钱,而且搜索引擎都喜欢更短的域名,例如京东更换的域名“jd.com”交易价格约 ...