Register for your free account! | Forgot your password?

Go Back   elitepvpers > MMORPGs > Conquer Online 2 > CO2 Programming
You last visited: Today at 13:13

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



[Release]Async Sockets (No packet-splitter)

Discussion on [Release]Async Sockets (No packet-splitter) within the CO2 Programming forum part of the Conquer Online 2 category.

Reply
 
Old   #1
 
elite*gold: 0
Join Date: Dec 2011
Posts: 1,537
Received Thanks: 785
[Release]Async Sockets (No packet-splitter)

So after seeing this thread:

I thought I'd make some socket server that could handle the packets without needing to split.

Source:

Example usage:

Server:

Client:

I hope you'll find this useful

Enjoy!
I don't have a username is offline  
Thanks
7 Users
Old 09/19/2012, 00:05   #2
 
elite*gold: 0
Join Date: Sep 2012
Posts: 775
Received Thanks: 329
im so **** thankful this is inspiring XD
go for it is offline  
Old 09/19/2012, 00:55   #3
 
InfamousNoone's Avatar
 
elite*gold: 20
Join Date: Jan 2008
Posts: 2,012
Received Thanks: 2,885
You may have tested this on a private server and had success, but I noticed one thing in your receive body (as well as your receive header) part which will fail in a proxy environment. You may the assumption when you say "I want to receive n-bytes" you receive n-bytes, and if you don't, you drop the connection. In the real world however, fragmentation occurs and you may only receive a fraction of a n-bytes and may need to continue receiving until n-bytes has been read in total.
InfamousNoone is offline  
Thanks
3 Users
Old 09/19/2012, 01:07   #4
 
elite*gold: 0
Join Date: Dec 2011
Posts: 1,537
Received Thanks: 785
Quote:
Originally Posted by InfamousNoone View Post
You may have tested this on a private server and had success, but I noticed one thing in your receive body (as well as your receive header) part which will fail in a proxy environment. You may the assumption when you say "I want to receive n-bytes" you receive n-bytes, and if you don't, you drop the connection. In the real world however, fragmentation occurs and you may only receive a fraction of a n-bytes and may need to continue receiving until n-bytes has been read in total.
Ohh yeah I didn't think of that! I'll update this tomorrow also found a few other things to change
I don't have a username is offline  
Old 09/19/2012, 02:11   #5
 
Danial Eugen's Avatar
 
elite*gold: 0
Join Date: Sep 2012
Posts: 171
Received Thanks: 68
Amazing work i was arranging a guide for that xD but you did :P.

Really nice code.

But in DataPacket.cs why don't you just turn the buffer to read only and rename it
Code:
        private readonly byte[] _buffer;
To prevent using this. redundantly ?

Code:
        public DataPacket(byte[] buffer)
        {
            this.buffer = new byte[buffer.Length];
            System.Buffer.BlockCopy(buffer, 0, this.buffer, 0, buffer.Length);
        }
It is really misleading to have 2 byte[] with the same name.

Also i see you never used this name spaces
Code:
using System;
using System.Collections.Generic;
using System.Linq;
See this edited DataPacket.cs
Danial Eugen is offline  
Old 09/19/2012, 02:34   #6
 
elite*gold: 0
Join Date: Dec 2011
Posts: 1,537
Received Thanks: 785
Let me break this down to you.

Quote:
Originally Posted by Danial Eugen View Post
that xD but you did :P.

Really nice code.

But in DataPacket.cs why don't you just turn the buffer to read only and rename it
Code:
        private readonly byte[] _buffer;
To prevent using this. redundantly ?

Code:
        public DataPacket(byte[] buffer)
        {
            this.buffer = new byte[buffer.Length];
            System.Buffer.BlockCopy(buffer, 0, this.buffer, 0, buffer.Length);
        }
It is really misleading to have 2 byte[] with the same name.
Felt lazy and the datapacket is just a class I'm using over and over and never really modifying it. Hence why it's not commented or documented at all.

Quote:
Originally Posted by Danial Eugen View Post
Also i see you never used this name spaces
Code:
using System;
using System.Collections.Generic;
using System.Linq;
I'm not wasting my time removing namespaces that I don't use and as I can't remember the short key for it then as lazy as I am I'll just leave them and the System namespace is always in use lol, so it'd be Collections.Generic and Linq only.

Some more constructive feed back would be nice instead this...
I don't have a username is offline  
Thanks
1 User
Old 09/19/2012, 02:48   #7
 
Danial Eugen's Avatar
 
elite*gold: 0
Join Date: Sep 2012
Posts: 171
Received Thanks: 68
Quote:
Originally Posted by I don't have a username View Post
Let me break this down to you.



Felt lazy and the datapacket is just a class I'm using over and over and never really modifying it. Hence why it's not commented or documented at all.



I'm not wasting my time removing namespaces that I don't use and as I can't remember the short key for it then as lazy as I am I'll just leave them and the System namespace is always in use lol, so it'd be Collections.Generic and Linq only.

Some more constructive feed back would be nice instead this...
Well you find this non constructive

i was just pointing you out because i wanted your code to be elegant and clean ;However, i see your code perfect and doing the job...

Also in DataPacket you don't have to add using System;, simply because you only needed it 2 time but you just added System before the code

Like
Code:
System.Buffer.BlockCopy(buffer, 0, _buffer, 0, buffer.Length);
Also can i use your Method of writing and reading (DataPacket.cs) the packets in my -non conquer related- project ? it will save me sometime writing one
Danial Eugen is offline  
Old 09/19/2012, 03:29   #8
 
elite*gold: 0
Join Date: Dec 2011
Posts: 1,537
Received Thanks: 785
Quote:
Originally Posted by Danial Eugen View Post
Well you find this non constructive

i was just pointing you out because i wanted your code to be elegant and clean ;However, i see your code perfect and doing the job...

Also in DataPacket you don't have to add using System;, simply because you only needed it 2 time but you just added System before the code

Like
Code:
System.Buffer.BlockCopy(buffer, 0, _buffer, 0, buffer.Length);
Also can i use your Method of writing and reading (DataPacket.cs) the packets in my -non conquer related- project ? it will save me sometime writing one
I like to type the whole namespace out for System.Buffer. Most likely a personal preference and yes you can lol it's not like it's anything special.
I don't have a username is offline  
Thanks
2 Users
Old 09/19/2012, 03:36   #9
 
Danial Eugen's Avatar
 
elite*gold: 0
Join Date: Sep 2012
Posts: 171
Received Thanks: 68
hehe i thought you used `System.Buffer` because if you turned it to Buffer it will conflict with
Code:
        protected byte[] Buffer
        {
            get
            {
                return _buffer;
            }
        }
Danial Eugen is offline  
Old 09/19/2012, 03:52   #10
 
elite*gold: 0
Join Date: Dec 2011
Posts: 1,537
Received Thanks: 785
Quote:
Originally Posted by Danial Eugen View Post
hehe i thought you used `System.Buffer` because if you turned it to Buffer it will conflict with
Code:
        protected byte[] Buffer
        {
            get
            {
                return _buffer;
            }
        }
Even if it didn't then I'd still have typed it out.
I don't have a username is offline  
Thanks
1 User
Old 09/19/2012, 23:40   #11
 
elite*gold: 0
Join Date: Sep 2012
Posts: 775
Received Thanks: 329
i've had some hard time understanding IAsyncResult and call backs , so i did search
and here what i found out (i did fully understand it as it was explained in pretty easy way and WAY BETTER than msdn ) so im sharing them for everyone
Quote:
The IAsyncResult interface represents an operation (such as a web request or a database call) that is running in the background, while your code continues to execute. It can tell you whether the operation finished (the IsCompleted property). It also gives you a WaitHandle object (the AsyncWaitHandle property) which can be used to wait until the operation finishes. (By calling result.AsyncWaitHandle.WaitOne())

You get an IAsyncResult by calling a BeginWhatever method. (BeginExecuteReader, BeginGetResponse, and many others). The BeginWhatever method will take any parameters needed for the operation (For example, BeginExecuteReader can take a CommandBehavior parameter), and can take an AsyncCallback delegate (not interface) and a state parameter. In returns an IAsyncResult object.

The AsyncCallback delegate is a method that you supply, which will be called when the operation finishes. It will usually be called on a different thread, so be careful in it. Your AsyncCallback method will be given the same IAsyncResult that the BeginWhatever method gave you earlier. The state parameter is put into the IAsyncResult and ignored by the system; you can use it in your AsyncCallback method to keep track of what the operation was for. (The state can be whatever you want it to be, including null)

Inside your AsyncCallback (or anywhere else), you can call the EndWhatever method that corresponds to the BeginWhatever method you called in the first place. You have to give it the IAsyncResult from BeginWhatever or from the AsyncCallback. When you call it, it will wait for the operation to finish (if it isn't already finished), and then give you back the operation's result. (Assuming the operation returns something; for example, WebRequest.EndGetResponse will return a WebResponse). If any error occurred during the operation, EndWhatever will throw an exception.
Quote:
A common use of internal access is in component-based development because it enables a group of components to cooperate in a private manner without being exposed to the rest of the application code. For example, a framework for building graphical user interfaces could provide Control and Form classes that cooperate using members with internal access. Since these members are internal, they are not exposed to code that is using the framework.
Quote:
EndAccept completes a call to BeginAccept. Before calling BeginAccept, you need to create a callback method that implements the AsyncCallback delegate. This callback method executes in a separate thread, and is called by the system after the BeginAccept method returns. It must accept the asyncResult parameter returned from the BeginAccept method.

Within the callback method, call the AsyncState method of the asyncResult parameter to obtain the Socket on which the connection attempt is being made. After obtaining the Socket, you can call the EndAccept method to successfully complete the connection attempt.

The EndAccept method blocks until a connection is pending in the incoming connection queue. The EndAccept method accepts the incoming connection and returns a new Socket that can be used to send data to and receive data from the remote host.
Quote:
The EndReceive method completes the asynchronous read operation started in the BeginReceive method.

Before calling BeginReceive, you need to create a callback method that implements the AsyncCallback delegate. This callback method executes in a separate thread and is called by the system after BeginReceive returns. The callback method must accept the IAsyncResult returned by the BeginReceive method as a parameter.

Within the callback method, call the AsyncState method of the IAsyncResult to obtain the state object passed to the BeginReceive method. Extract the receiving Socket from this state object. After obtaining the Socket, you can call the EndReceive method to successfully complete the read operation and return the number of bytes read.

The EndReceive method will block until data is available. If you are using a connectionless protocol, EndReceive will read the first enqueued datagram available in the incoming network buffer. If you are using a connection-oriented protocol, the EndReceive method will read as much data as is available up to the number of bytes you specified in the size parameter of the BeginReceive method. If the remote host shuts down the Socket connection with the Shutdown method, and all available data has been received, the EndReceive method will complete immediately and return zero bytes.

To obtain the received data, call the AsyncState method of the IAsyncResult, and extract the buffer contained in the resulting state object.

To cancel a pending BeginReceive, call the Close method.
Quote:
The Monitor class controls access to objects by granting a lock for an object to a single thread. Object locks provide the ability to restrict access to a block of code, commonly called a critical section. While a thread owns the lock for an object, no other thread can acquire that lock. You can also use Monitor to ensure that no other thread is allowed to access a section of application code being executed by the lock owner, unless the other thread is executing the code using a different locked object.

Monitor.TryEnter(Object, int32) Attempts to acquire an exclusive lock on the specified object, and atomically sets a value that indicates whether the lock was taken.

Monitor.Exit Releases an exclusive lock on the specified object.


i took those form msdn as those what jacob used at this example , one does the look for 50 ms which is enough to try sending the packet and one release the lock so the next buffer could use baseSocket.BeginSend

check out for more
i duno why i find this better than locks >.<
to be edited if i found another method/interface that i can't understand and found good explanation for it around
so far i've mentioned iasyncresult , internal and socket endaccept , and yes im going in sequence as im reading it (also doing a flow chart with methods on sketch to fully understand the logic and how the system work)
btw most of information i post and explanation is from stackoverflow and msdn


---------------------------------------------------------------------------------------------
hybrid i got question about
Quote:
You may have tested this on a private server and had success, but I noticed one thing in your receive body (as well as your receive header) part which will fail in a proxy environment. You may the assumption when you say "I want to receive n-bytes" you receive n-bytes, and if you don't, you drop the connection. In the real world however, fragmentation occurs and you may only receive a fraction of a n-bytes and may need to continue receiving until n-bytes has been read in total.
thanks for this information , but i got a question , i should not disconnect if i didn't receive the size of packet i read on the header , i should continue receiving until i get that n-bytes , so they may get delayed but server must send it , right ?
----------------------------------------------------------------------------------------------
jacob i've been 19 hrs learning from this and i enjoyed it and the logic , also it improved my programming skills was damn confusing until i made something crazy which u may scream my face off for
here
go for it is offline  
Thanks
2 Users
Old 09/20/2012, 16:44   #12
 
InfamousNoone's Avatar
 
elite*gold: 20
Join Date: Jan 2008
Posts: 2,012
Received Thanks: 2,885
Quote:
Originally Posted by go for it View Post
---------------------------------------------------------------------------------------------
hybrid i got question about

thanks for this information , but i got a question , i should not disconnect if i didn't receive the size of packet i read on the header , i should continue receiving until i get that n-bytes , so they may get delayed but server must send it , right ?
Typically, you may not receive the entire packet at the same time this occurs to fragmentation. So, your code becomes circular until nBytes has been received like this (I haven't actually tested it, but it should give you a fairly good idea of what I mean by circular):

Code:
    public class ReceiveAsyncBuffer
    {
        public bool OperationInProgress { get; private set; }
        public byte[] Buffer { get; private set; }
        public int Received { get { return offset; } }

        private Socket target;
        private int offset;
        private int left;
        private Action<bool> callback;

        public ReceiveAsyncBuffer(int size)
        {
            Buffer = new byte[size];
        }
        public void Receive(Socket socket, int size, Action<bool> complete)
        {
            if (OperationInProgress)
                throw new InvalidOperationException("another receive operation is already in progress");
            if (complete == null)
                throw new ArgumentNullException("complete delegate cannot be null");

            this.target = socket;
            this.offset = 0;
            this.left = size;
            this.callback = complete;
            this.OperationInProgress = true;

            this.BlockReceive();
        }
        private void BlockReceive()
        {
            try
            {
                this.target.BeginReceive(this.Buffer, this.offset, this.left, SocketFlags.None,
                    (result) =>
                    {
                        try
                        {
                            int nRecv = this.target.EndReceive(result);
                            if (nRecv <= 0)
                            {
                                this.OperationInProgress = false;
                                this.callback(false); // fail
                            }
                            else
                            {
                                this.left -= nRecv;
                                this.offset += nRecv;
                                if (this.left == 0)
                                {
                                    this.OperationInProgress = false;
                                    this.callback(true); // done
                                }
                                else
                                    BlockReceive();
                            }

                        }
                        catch (Exception)
                        {
                            this.OperationInProgress = false;
                            this.callback(false);
                        }

                    }, null);
            }
            catch (Exception)
            {
                this.OperationInProgress = false;
                this.callback(false); // failed
            }
        }
    }
InfamousNoone is offline  
Thanks
3 Users
Old 09/20/2012, 17:35   #13
 
elite*gold: 0
Join Date: Dec 2011
Posts: 1,537
Received Thanks: 785
As I got quite busy yesterday with my presentation for exam which I had today and haven't got the time rewrite it then I'll eventually do it today I think
I don't have a username is offline  
Old 09/20/2012, 17:45   #14
 
Danial Eugen's Avatar
 
elite*gold: 0
Join Date: Sep 2012
Posts: 171
Received Thanks: 68
Quote:
Originally Posted by I don't have a username View Post
As I got quite busy yesterday with my presentation for exam which I had today and haven't got the time rewrite it then I'll eventually do it today I think
How was your exam :P
Danial Eugen is offline  
Old 09/20/2012, 19:03   #15
 
elite*gold: 0
Join Date: Dec 2011
Posts: 1,537
Received Thanks: 785
Quote:
Originally Posted by Danial Eugen View Post
How was your exam :P
Graduated with an A
I don't have a username is offline  
Thanks
1 User
Reply


Similar Threads Similar Threads
[Release] EXP/SP Rates splitter
02/18/2024 - SRO PServer Guides & Releases - 38 Replies
so,this project was only in underground section,but i decided to release it here, this is a patcher which sets sp rates,so now you can make smth like: exp rates:200x sp rates:300x download in attachments (source code included) this works only for vsro 188 serverfiles put it in your serverfiles folder,run Rates Splitter.exe (make sure your gameserver is called SR_GameServer.exe) and set your rates
Async Socket Wrapper
11/11/2011 - CO2 Programming - 8 Replies
So I was bored and thought I would code a socket wrapper. It's a class library, but full project is available for download + an example use for a socket server. It contains both wrapper for server and client stuff, which means it can be used for either private servers as server-socket or for a proxy. WinAsync - This class contains all the events. public delegate void WinEvent(WinClient wClient); public delegate void WinBufferEvent(WinClient wClient, WinBuffer Buffer); ...
[VK]Splitter entfernen!
06/08/2011 - Metin2 Trading - 0 Replies
Verkaufe Stein-Handbuch! Verkaufe auf S25 Leviathan einen Account(Level 1,hat ein Stein-Handbuch). Damit kannst du deine Splitter aus einen beliebiegen Gegenstand entfernen! Nehme nur E*Gold! Macht Gebote!
[How To]Splitter Enfernen
11/03/2008 - Metin2 Guides & Templates - 20 Replies
Hi, Ich sage euch nun wie ihr Splitter enfernen koennt wenn ihr welche in euren waffen bzw ruetungen habt.Das geht auf jedem Server (ausser deutschen)!.Zuerst muesst ihr lvl 25 erreicht haben was nicht ausserordentlich schwer ist auf longju,Us,chinatown usw :D.Danach geht ihr zu Deokbae (dem holzfaeller) in map2 und klickt auf ihn.Das muesste dann ca so aussehen : 黄金斧.Danach geht ihr (egal welches lvl ihr seit also koennt auch lvl 70 sein^^) St.Wilde Generaele killen.Irgendwann nach langem...
Splitter-,-
08/31/2008 - Metin2 Private Server - 15 Replies
huhu, wollt mal fragn ob es am markt auch splitter entfernen gibt? Und wenn ja wie sieht das aus? oder kann mir das jemand ingame verkaufn der itemshopt...



All times are GMT +1. The time now is 13:14.


Powered by vBulletin®
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2025 elitepvpers All Rights Reserved.