|
You last visited: Today at 11:50
Advertisement
Network programing question
Discussion on Network programing question within the SRO Coding Corner forum part of the Silkroad Online category.
06/20/2016, 09:28
|
#1
|
elite*gold: 0
Join Date: Feb 2009
Posts: 46
Received Thanks: 5
|
Network programing question
hello guys ,
i got 2 question's confused me alot :-
first , sro is based on tcp and as i know tcp is responsible to deliver all packets and arrange them but some times my program miss some packets. an example of alchemy bot :- i send alchemy packet 0x7150 and suppose to receive 0xb150 after ~ 4 sec but sometimes the bot w8 forever for 0xb150 without getting it .
second , high bandwidth consuming as example i create a clientless app just to login character to game server , it suppose to send the 0x2002 ping packet every ~5 sec
Size of Ethernet frame - 24 Bytes
Size of IPv4 Header (without any options) - 20 bytes
Size of TCP Header (without any options) - 20 Bytes
size of data = 6 bytes
so ping packet = 70 bytes but by monitoring network traffic by microsoft resource monitor , my app send more than 250 bytes per second .
here is the clientless code :-
Code:
class Clientless
{
public Clientless(int _No)
{
Current_Sec = Gate_sec;
Current_Sock = Gate_socket;
}
private Security Gate_sec = new Security();
private Security Agent_sec = new Security();
private Security Current_Sec;
//**********************************************
private Socket Gate_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
private Socket Agent_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
private Socket Current_Sock;
private TransferBuffer buffer = new TransferBuffer(8192);
private List<Packet> packets = new List<Packet>();
Stopwatch ping = new Stopwatch();
private bool firststart= true;
uint ID ;
public void Start(string ip , int port)
{
try
{
IPAddress IP = IPAddress.Parse(ip);
Current_Sock.Connect(IP, port);
Current_Sock.Blocking = false;
Current_Sock.NoDelay = true;
if (firststart)
{
MainMethod();
}
}
catch (Exception)
{
throw;
}
}
private void MainMethod()
{
while (!Exit)
{
if (Current_Sock.Poll(0, SelectMode.SelectRead))
{
buffer.Size = Current_Sock.Receive(buffer.Buffer, 0, buffer.Buffer.Length, SocketFlags.None);
if (buffer.Size == 0)
{
break;
}
Current_Sec.Recv(buffer);
}
List<Packet> packets = Current_Sec.TransferIncoming();
if (packets != null)
{
Receive(packets);
packets.Clear();
}
if (ping != null && ping.ElapsedMilliseconds >= 4999)
{
Packet response = new Packet(0x2002, false, false);
Current_Sec.Send(response);
ping.Restart();
}
if (Current_Sock.Poll(0, SelectMode.SelectWrite))
{
SendLogic();
}
Thread.Sleep(1);
}
dipose();
}
and here is the 0xA102
Code:
else if (packet.Opcode == 0xA102)
{
byte result = packet.ReadUInt8();
if (result == 0x01)
{
ID = packet.ReadUInt32();
string IP = packet.ReadAscii();
int port = packet.ReadUInt16();
Current_Sec = Agent_sec;
Current_Sock = Agent_socket;
try
{
Gate_socket.Close();
}
catch (Exception)
{
throw;
}
firststart = false;
Start(IP, port);
break;
}
Sorry for my bad english and Thanks om advance.
|
|
|
06/20/2016, 10:02
|
#2
|
elite*gold: 21
Join Date: Mar 2011
Posts: 1,613
Received Thanks: 1,122
|
Alright..
What is
Code:
private List<Packet> packets = new List<Packet>();
is declared for exactly? It has no use.
* Use a timer to send ping packet instead; Refer to this:  , code example:
Code:
<= Has to be in the packet handling =>
if (packet.Opcode == 0x2001)
{
aTimer.Enabled = true;
aTimer.Start();
Console.WriteLine("Ping Timer has been enabled!");
}
########################
System.Timers.Timer aTimer = new System.Timers.Timer();
aTimer.Elapsed+=new ElapsedEventHandler(PingEvent);
aTimer.Interval=5000;
aTimer.Enabled=false;
// Specify what you want to happen when the Elapsed event is raised.
private static void PingEvent(object source, ElapsedEventArgs e)
{
security.Send(new Packet(0x2002));
}
* Remove the socket.poll related code, it's useless in such a thing.
If possible just re-code the whole thing, look at Supermike filter, you can use the base and adjust it a little to fit the clientless.
My A102 in case it could help even a little:
Code:
if (packet.Opcode == 0xA102)
{
byte flag = packet.ReadUInt8();
if (flag == 1)
{
uint m_sessionId = packet.ReadUInt32();
string m_serverIp = packet.ReadAscii();
ushort m_serverPort = packet.ReadUInt16();
GameContext game = new GameContext();
game.Connect(m_serverIp, m_serverPort, m_sessionId, m_username, m_password);
}
}
|
|
|
06/20/2016, 18:13
|
#3
|
elite*gold: 0
Join Date: Oct 2015
Posts: 4
Received Thanks: 4
|
Quote:
Originally Posted by Skipper*
Code:
<= Has to be in the packet handling =>
if (packet.Opcode == 0x2001)
{
aTimer.Enabled = true;
aTimer.Start();
Console.WriteLine("Ping Timer has been enabled!");
}
########################
System.Timers.Timer aTimer = new System.Timers.Timer();
aTimer.Elapsed+=new ElapsedEventHandler(PingEvent);
aTimer.Interval=5000;
aTimer.Enabled=false;
// Specify what you want to happen when the Elapsed event is raised.
private static void PingEvent(object source, ElapsedEventArgs e)
{
security.Send(new Packet(0x2002));
}
|
I dont think this code is right, 0x2001 opcode is a part of hankshake process, you get that package twice, one for GS one for AG.
|
|
|
06/20/2016, 18:52
|
#4
|
elite*gold: 0
Join Date: Feb 2009
Posts: 46
Received Thanks: 5
|
thanks for fast response guys ,
Quote:
What is
Code:
private List<Packet> packets = new List<Packet>();
is declared for exactly? It has no use.
|
i used it in the Receive(packets) function :-
Code:
private void Receive(List<Packet> Packetlist)
foreach (Packet packet in Packetlist)
{
if (packet.Opcode==0x5000||packet.Opcode==0x9000)
{
continue;
}
// ETC ......................................
}
I dont think this code is right, 0x2001 opcode is a part of hankshake process, you get that package twice, one for GS one for AG.
Here is my 0x2001
Code:
#region 0x2001
if (packet.Opcode == 0x2001)
{
string str= packet.ReadAscii();
if (str== "GatewayServer")
{
Packet response = new Packet(0x6100, true, false);
response.WriteUInt8(0x16);
response.WriteAscii("SR_Client");
response.WriteUInt32(Globals.version);
Current_Sec.Send(response);
ping.Start();
}
else
{
Packet response = new Packet(0x6103, true, false);
response.WriteUInt32(ID);
response.WriteAscii(username);
response.WriteAscii(password);
response.WriteUInt8(0x16);
response.WriteUInt32(0);
response.WriteUInt16(0);
Current_Sec.Send(response);
}
}
#endregion
Quote:
|
Use a timer to send ping packet instead
|
i was using timer's but by little searching i found that timer execute on different Thread and some one advise me to avoid use multi threading if i can , so my question does my code rly need timers ?
Quote:
|
Remove the socket.poll related code, it's useless in such a thing.
|
ok i will remove it .
|
|
|
06/20/2016, 19:18
|
#5
|
elite*gold: 0
Join Date: Oct 2015
Posts: 4
Received Thanks: 4
|
Quote:
Originally Posted by theking200051
i was using timer's but by little searching i found that timer execute on different Thread and some one advise me to avoid use multi threading if i can , so my question does my code rly need timers ?
ok i will remove it .
|
No you dont need timers, you dont even need a StopWatch. This is from my working code;
Code:
public class SilkroadClient
{
private static readonly Packet Ping = new Packet(0x2002);
//....
private void Connection_Loop()
{
long now, lastPing = now = Environment.TickCount;
while (true)
{
//handle incoming packets
now = Environment.TickCount;
if (now - lastPing >= 5000)
{
_security.Send(Ping);
lastPing = now;
}
//handle outgoing packets
var tmp_buffers = _security.TransferOutgoing();
//...
Thread.Sleep(1);
}
}
//...
}
|
|
|
06/21/2016, 08:11
|
#6
|
elite*gold: 0
Join Date: Oct 2014
Posts: 34
Received Thanks: 16
|
Quote:
Originally Posted by theking200051
i send alchemy packet 0x7150 and suppose to receive 0xb150 after ~ 4 sec but sometimes the bot w8 forever for 0xb150 without getting it .
|
Sometimes SRO-Server didnt got the package or just didnt handled it..
Some timeouts occured on any side.. lags.. whatever!
So you will need a timeout-timer .. after x seconds (time should be editable!) without receiving the desired answer RESEND your fuse packet!
|
|
|
06/21/2016, 16:17
|
#7
|
elite*gold: 0
Join Date: Feb 2009
Posts: 46
Received Thanks: 5
|
Quote:
Originally Posted by mxii
Sometimes SRO-Server didnt got the package or just didnt handled it..
Some timeouts occured on any side.. lags.. whatever!
So you will need a timeout-timer .. after x seconds (time should be editable!) without receiving the desired answer RESEND your fuse packet!
|
thanks for replay ,so packet loss is something normal with any tcp connection?
and in my client side does the code is responsible too for the packet loss or just the modem & ISP & LAN & etc......
|
|
|
06/21/2016, 16:23
|
#8
|
elite*gold: 0
Join Date: Oct 2014
Posts: 34
Received Thanks: 16
|
Quote:
Originally Posted by theking200051
thanks for replay ,so packet loss is something normal with any tcp connection?
and in my client side does the code is responsible too for the packet loss or just the modem & ISP & LAN & etc......
|
Normally NOT!
TCP will repeat those "lost packets" but only a specific number of retries. (without your knowledge .. anywhere in the TCP-Stack!)
But in this case (already coded a alchemy tool, too) the server gets your packet but didnt handled it.
Cant tell you why..
So in all SRO-Coding cases i would highly recommend you to program all your stuff ASYNC!
And if there is no answer after a specific timeout (5-60 seconds) just retry it!
During some lags the server will not response to your alchemy packet.. to your open NPC packet.. walk packet or whatever!
gl!
|
|
|
06/21/2016, 18:20
|
#9
|
elite*gold: 0
Join Date: Oct 2015
Posts: 4
Received Thanks: 4
|
Quote:
Originally Posted by mxii
Normally NOT!
TCP will repeat those "lost packets" but only a specific number of retries. (without your knowledge .. anywhere in the TCP-Stack!)
|
No actually TCP provides reliable, ordered, and error-checked delivery of data. If TPC fails to transmit a packet it will keep trying to deliver it. There is no "specific number of retries" If it keep failing to transmit the data you will end up with an IOException. But TCP is running at 4th(Transport) layer of 7 Layered OSI (Open Systems Interconnection) Model. Which means TCP only provides reliable, ordered, and error-checked delivery of data up to 4th layer.
5th, 6th Layer (usually the Operating System) or 7th layer which is application itself can still drop/corrupt or as in silkroad server's case discard packages.
More info on OSI Model and TCP
|
|
|
06/22/2016, 17:31
|
#10
|
elite*gold: 0
Join Date: Feb 2009
Posts: 46
Received Thanks: 5
|
Quote:
Originally Posted by mrnoad
No actually TCP provides reliable, ordered, and error-checked delivery of data. If TPC fails to transmit a packet it will keep trying to deliver it. There is no "specific number of retries" If it keep failing to transmit the data you will end up with an IOException. But TCP is running at 4th(Transport) layer of 7 Layered OSI (Open Systems Interconnection) Model. Which means TCP only provides reliable, ordered, and error-checked delivery of data up to 4th layer.
5th, 6th Layer (usually the Operating System) or 7th layer which is application itself can still drop/corrupt or as in silkroad server's case discard packages.
More info on OSI Model and TCP
|
so the packets is fully received error free and ordered up to the 4th layer but it drop or corrupt in the 5th or 6th or 7th layer's that handled by my app Socket right ?
so the question is the packet dropping caused 100 % by my code or something else , and how to avoid such behavior ?
|
|
|
06/22/2016, 18:24
|
#11
|
elite*gold: 0
Join Date: Oct 2015
Posts: 4
Received Thanks: 4
|
Quote:
Originally Posted by theking200051
so the packets is fully received error free and ordered up to the 4th layer but it drop or corrupt in the 5th or 6th or 7th layer's that handled by my app Socket right ?
so the question is the packet dropping caused 100 % by my code or something else , and how to avoid such behavior ?
|
The thing is if some packets dropped or corrupted at 5th(session) or 6th(presentation) layer that means its either the operating system or the hardware is faulty or firewall/antivirus is blocking your data. And unless you are a system/hardware programmer or system admin you dont deal with these kind of failures. Your job is about bugs as a software programmer.
Now about 7th(application) layer,
If your software discard some data it receives that's a choice. If your software without intention, skip/drops some data it receives or if it try to read a String while data contains an Integer, those are the bugs you should be worry.
|
|
|
Similar Threads
|
[C#]need help on network programing
03/30/2013 - SRO Coding Corner - 12 Replies
i need reference for methods which i can send , receive and parse packets Iam not good in C# i learned and understood the logic of packets but i already don't how to send packet
and i looked on projects like zbot src and couldn't understand it
BTW:sry for bad English
|
[HELP] One question about programing
03/11/2011 - SRO Coding Corner - 37 Replies
Hi. I want to know what i need to create bot . Like mbot, ribot, ibot and etc..
What programing skills and what type of programing(c++,vb..). ?
|
[Programing] what is the best programing launguage
10/31/2010 - CO2 Programming - 19 Replies
hi i am willing to learn a new programming launguage to create bots witch i will post for free useing so if you can please tell me what is the best one to learn i will start learning it as soon as possible i allready know a bit about VB
|
All times are GMT +1. The time now is 11:50.
|
|