473,836 Members | 1,534 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Extremly fast dinamic array implementation

I just want to share some code with you, and have some comments and
improvements if you want.
This header file allocates and add and delete items of any kind of data
from a very fast array:

#include <stdlib.h>

#ifndef __LIST_H__
#define __LIST_H__

#define NEW(type) (type*)malloc(s izeof(type))

#define DEFAULT_SIZE 12

#define lNEW(type) ({ \
int *list = (int*)malloc( (sizeof(type)*D EFAULT_SIZE) \
+ (sizeof(int)*3) ); \
*list++=sizeof( type); \
*list++=DEFAULT _SIZE; \
*list++=0; \
(type*)list; })

#define lSIZE(list) (*((int*)list-1))
#define lALLOCATED(list ) (*((int*)list-2))
#define lOBJECTSIZE(lis t) (*((int*)list-3))
#define lNEWITEM(list) ({ \
if (lSIZE(list)>=l ALLOCATED(list) ) { \
list = (void*) ((int*)realloc( (int*)list-3, \
(lSIZE(list) + DEFAULT_SIZE) * \
lOBJECTSIZE(lis t) + \
sizeof(int)*3) \
+ 3); \
lALLOCATED(list )+=DEFAULT_SIZE ; \
} \
&list[lSIZE(list)++]; \
})

#define lAPPEND(list,ob j) *lNEWITEM(list) =obj;
#define lDELITEM(list,o bj) *obj=list[--lSIZE(list)]

#define lFREE(list) free((int*)list-3)

#endif

In my system, it is able to add more than 1.000.000 of items per
second, so I think it is quite fast.
And the interesting thing is that you can use the resulting array as a
normal C array, using [] to access all of its data.
Example:

typedef struct {
int onething;
char *another;
} Object;
Object *obj = lNEW(Object);
Object o = {12, "haha"};
Object *oo = lNEWITEM(obj);
lAPPEND(obj, o);
oo->another="hehe" ;
printf ("%i, %s", lSIZE(obj), obj[1].another);

=prints "2, hehe"

I'm using GCC. If anyone wants to check out it using other compilers, I
will thank.

Aug 9 '06 #1
10 3021
ja*****@gmail.c om wrote:
I just want to share some code with you, and have some comments and
improvements if you want.
This header file allocates and add and delete items of any kind of
data from a very fast array:

#include <stdlib.h>

#ifndef __LIST_H__
#define __LIST_H__

#define NEW(type) (type*)malloc(s izeof(type))

#define DEFAULT_SIZE 12

#define lNEW(type) ({ \
int *list = (int*)malloc( (sizeof(type)*D EFAULT_SIZE) \
+ (sizeof(int)*3) ); \
*list++=sizeof( type); \
*list++=DEFAULT _SIZE; \
*list++=0; \
(type*)list; })

#define lSIZE(list) (*((int*)list-1))
#define lALLOCATED(list ) (*((int*)list-2))
#define lOBJECTSIZE(lis t) (*((int*)list-3))
#define lNEWITEM(list) ({ \
if (lSIZE(list)>=l ALLOCATED(list) ) { \
list = (void*) ((int*)realloc( (int*)list-3, \
(lSIZE(list) + DEFAULT_SIZE) * \
lOBJECTSIZE(lis t) + \
sizeof(int)*3) \
+ 3); \
lALLOCATED(list )+=DEFAULT_SIZE ; \
} \
&list[lSIZE(list)++]; \
})

#define lAPPEND(list,ob j) *lNEWITEM(list) =obj;
#define lDELITEM(list,o bj) *obj=list[--lSIZE(list)]

#define lFREE(list) free((int*)list-3)

#endif

In my system, it is able to add more than 1.000.000 of items per
second, so I think it is quite fast.
And the interesting thing is that you can use the resulting array as a
normal C array, using [] to access all of its data.
Example:

typedef struct {
int onething;
char *another;
} Object;
Object *obj = lNEW(Object);
Object o = {12, "haha"};
Object *oo = lNEWITEM(obj);
lAPPEND(obj, o);
oo->another="hehe" ;
printf ("%i, %s", lSIZE(obj), obj[1].another);

=prints "2, hehe"

I'm using GCC. If anyone wants to check out it using other compilers,
I will thank.

On my system, Object *obj = lNEW(Object); expands to ...

Object *obj = ({ int list = (int)malloc( (sizeof(Object) *12) +
(sizeof(int)*3) ); *list++=sizeof( Object); *list++=12; *list++=0;
(Object*)list; });

Where should one start - the parenthesied compound statement used in the
assignment perhaps?
--
==============
Not a pedant
==============
Aug 9 '06 #2

ja*****@gmail.c om wrote:
I just want to share some code with you, and have some comments and
improvements if you want.
Some comments:
(1)
It's usually a poor idea to use macros to generate substantial amounts
of code. Just one slip of the finger and the poor user will get tons
of error messages, showing tons of lines of mysterious fractured code.
How about you use some nice functions or methods?

(2) It's usually a bad sign when there's not a single error check in a
piece of complex code that can go wrong so many ways.

(3) You're schlepping off all the hard work to your particular
implementation of malloc and realloc().

otherwise okay

Aug 9 '06 #3

Ancient_Hacker wrote:
ja*****@gmail.c om wrote:
I just want to share some code with you, and have some comments and
improvements if you want.

Some comments:
(1)
It's usually a poor idea to use macros to generate substantial amounts
of code. Just one slip of the finger and the poor user will get tons
of error messages, showing tons of lines of mysterious fractured code.
How about you use some nice functions or methods?
I use macros because it is posible to typecast easily and
transparently, and also because they are fast. (Yes, I could use inline
functions, but still have problems managin type sizes and more.)
(2) It's usually a bad sign when there's not a single error check in a
piece of complex code that can go wrong so many ways.
Having error check is against the original intention of being fast.
With current computers, being able to allocate 4Gb or more of memory,
there is no need for such comprobations in most situations. Elsewhere,
if a program using dinamic arrays gets out of memory, the system itself
will halt down de application, so I don't agree that a memory check
would be necesary here.
(3) You're schlepping off all the hard work to your particular
implementation of malloc and realloc().

otherwise okay
Thanks for your coments.

Aug 9 '06 #4
pemo wrote:
On my system, Object *obj = lNEW(Object); expands to ...

Object *obj = ({ int list = (int)malloc( (sizeof(Object) *12) +
(sizeof(int)*3) ); *list++=sizeof( Object); *list++=12; *list++=0;
(Object*)list; });

Where should one start - the parenthesied compound statement used in the
assignment perhaps?
Bassically, what it does is to allocate a cache of objects (12 is its
size, but you can change it), and 3 more integers, which allocate each
one the size of the object, the cache size, and the actual size of the
dinamic array.
Yo can access the size of the array because it is allocated 1 point
before the address of the array. Also you access the cache size and the
size of each allocated object substracting 2 and 3 from the address of
the pointer.
In this way, you can use any object of any type and size, without
restriction and without typecast problems (as there are in GLIB, for
example).

Aug 9 '06 #5
ja*****@gmail.c om wrote:
pemo wrote:

>>On my system, Object *obj = lNEW(Object); expands to ...

Object *obj = ({ int list = (int)malloc( (sizeof(Object) *12) +
(sizeof(int)* 3)); *list++=sizeof( Object); *list++=12; *list++=0;
(Object*)list ; });

Where should one start - the parenthesied compound statement used in the
assignment perhaps?


Bassically, what it does is to allocate a cache of objects (12 is its
size, but you can change it), and 3 more integers, which allocate each
one the size of the object, the cache size, and the actual size of the
dinamic array.
Yo can access the size of the array because it is allocated 1 point
before the address of the array. Also you access the cache size and the
size of each allocated object substracting 2 and 3 from the address of
the pointer.
In this way, you can use any object of any type and size, without
restriction and without typecast problems (as there are in GLIB, for
example).
"Without restriction?" How do you handle a type whose
alignment requirement is stricter than int's? For example,
on a system with four-byte int and eight-byte double, where
double requires alignment on an eight-byte boundary, your
macro mis-aligns all the doubles.

--
Eric Sosman
es*****@acm-dot-org.invalid
Aug 9 '06 #6
ja*****@gmail.c om wrote:
I just want to share some code with you, and have some comments and
improvements if you want.
This header file allocates and add and delete items of any kind of data
from a very fast array:

#include <stdlib.h>

#ifndef __LIST_H__
#define __LIST_H__

#define NEW(type) (type*)malloc(s izeof(type))

#define DEFAULT_SIZE 12

#define lNEW(type) ({ \
int *list = (int*)malloc( (sizeof(type)*D EFAULT_SIZE) \
+ (sizeof(int)*3) ); \
*list++=sizeof( type); \
*list++=DEFAULT _SIZE; \
*list++=0; \
(type*)list; })

#define lSIZE(list) (*((int*)list-1))
#define lALLOCATED(list ) (*((int*)list-2))
#define lOBJECTSIZE(lis t) (*((int*)list-3))
#define lNEWITEM(list) ({ \
if (lSIZE(list)>=l ALLOCATED(list) ) { \
list = (void*) ((int*)realloc( (int*)list-3, \
(lSIZE(list) + DEFAULT_SIZE) * \
lOBJECTSIZE(lis t) + \
sizeof(int)*3) \
+ 3); \
lALLOCATED(list )+=DEFAULT_SIZE ; \
} \
&list[lSIZE(list)++]; \
})

#define lAPPEND(list,ob j) *lNEWITEM(list) =obj;
#define lDELITEM(list,o bj) *obj=list[--lSIZE(list)]

#define lFREE(list) free((int*)list-3)

#endif
It is a strange policy, you add/remove elements only at the end, but you
allow random access? A mix between a stack and an array? (but definitely
not a list).
In my system, it is able to add more than 1.000.000 of items per
second, so I think it is quite fast.
This is not quite fast. >100.000.000 is quite fast (on a Pentium-M
1.6Ghz). The best is to compare it the speed of the C array ;-)
And the interesting thing is that you can use the resulting array as a
normal C array, using [] to access all of its data.
According to my experience, I think it is a good idea to have C-like
access for low-level very fast arrays, but it is not a good idea to mix
it with append/remove-like functions. For low-level, C-like array random
access, checked get/set and resize are a better choice. Function like
cat/append/remove start to be high level functions where the user should
not be concerned by the fact that the array pointer may change after a
cat/append, that is the array should stay the same even when its
capacity increases.
Example:

typedef struct {
int onething;
char *another;
} Object;
Object *obj = lNEW(Object);
Object o = {12, "haha"};
Object *oo = lNEWITEM(obj);
lAPPEND(obj, o);
oo->another="hehe" ;
printf ("%i, %s", lSIZE(obj), obj[1].another);

=prints "2, hehe"

I'm using GCC. If anyone wants to check out it using other compilers, I
will thank.
Here is below the header of a low-level fast array interface
(implementation is an easy exercise ;-) ) which is part of my OOC
framework (required to compile, but easy to make it independent). It
allows C random access to data, it is type safe and do not use macros
(except for prefixing and some shortcuts, the later can be remove). Your
example becomes (adapted to array, not stack):

Object *obj = obj_array_new(2 );
obj[0] = (Object*){12, "haha"};
obj[1] = obj[0];
obj[1].another = "hehe";
printf("%i, %s", sizeof *obj, obj[1].another);

it is easy to make a generic stack on top of this array implementation.

a+, ld.

-----------------
/* template file, multiple inclusion allowed */

/*
*************** ***************
* Raw Array interface
* -----
* Object Oriented C programming
*
* Author: Laurent Deniau, La************@ cern.ch
*
* $Id: array_t.h,v 1.1 2004/07/04 13:52:09 ldeniau Exp $
*
* For more information, please see:
* http://cern.ch/Laurent.Deniau/html/ooc/ooc.html
*
*************** ***************
*/

/* NOTE-USER: raw array interface

array_T : element type (e.g. int)
array_T*: array type (e.g. int*)

array_T* PREFIX_array_ne w (size_t cnt );
array_T* PREFIX_array_al loc (size_t cnt );
array_T* PREFIX_array_cp y (array_T *a1 , const array_T *a2);
array_T* PREFIX_array_ra wcpy (array_T *a1 , const array_T *src,
size_t cnt);
array_T* PREFIX_array_du p (const array_T *a );
array_T* PREFIX_array_ra wdup (const array_T *src, size_t cnt);
array_T* PREFIX_array_re size (array_T *a , size_t cnt);
array_T* PREFIX_array_re alloc(array_T *a , size_t cnt);
void PREFIX_array_de l (array_T *a );
void PREFIX_array_fr ee (array_T *a );
size_t PREFIX_array_cn t (const array_T *a );
array_T PREFIX_array_ge t (const array_T *a, size_t idx);
void PREFIX_array_se t (array_T *a, size_t idx, array_T val);
*/

#ifndef array_T
#error "libooc: missing array_T definition"
#endif

#ifndef array_PREFIX
#define array_PREFIX array_T
#endif

/*
* ----------
* Externals
* ----------
*/

void* ooc_array_new_ ( size_t cnt , size_t esize,
size_t hsize, bool ex);
void* ooc_array_resiz e_(void* self, size_t cnt , size_t esize,
size_t hsize, bool ex);
void* ooc_array_cpy_ (void* dst , const void* src, size_t esize,
size_t hsize);
void* ooc_array_rawcp y_(void* dst , const void* src, size_t esize,
size_t hsize, size_t cnt);
void* ooc_array_dup_ ( const void* src, size_t esize,
size_t hsize);
void* ooc_array_rawdu p_( const void* src, size_t esize,
size_t hsize, size_t cnt);
void ooc_array_badrn g_(const char *file, int line);

/*
* ---------------------------------------
* Array interface/inlined implementation
* ---------------------------------------
*/

#ifndef OOC_TYPE_ARRAY_ C

#define T OOC_CAT(array_P REFIX, _array)
#define F(f) OOC_CAT3(T,_,f)
#define B(p) ((struct T*)((char*)(p) - offsetof(struct T, data)))

struct T {
const size_t cnt; /* read-only field */
#if OOC_ISO_C < OOC_ISO_C99
array_T data[1]; /* public field, undefined behavior, but... */
#else
array_T data[]; /* public field, defined behavior */
#endif
};

static inline array_T*
F(new) (size_t cnt)
{
return
ooc_array_new_( cnt, sizeof(array_T) , offsetof(struct T, data), true);
}

static inline array_T*
F(alloc) (size_t cnt)
{
return
ooc_array_new_( cnt, sizeof(array_T) , offsetof(struct T, data), false);
}

static inline array_T*
F(cpy) (array_T *dst, const array_T *src)
{
return ooc_array_cpy_( (void*)dst, (void*)src,
sizeof(array_T) , offsetof(struct T, data));
}

static inline array_T*
F(rawcpy) (array_T *dst, const array_T *src, size_t cnt)
{
return ooc_array_rawcp y_((void*)dst, (void*)src,
sizeof(array_T) , offsetof(struct T, data), cnt);
}

static inline array_T*
F(dup) (const array_T *src)
{
return ooc_array_dup_( (void*)src, sizeof(array_T) ,
offsetof(struct T, data));
}

static inline array_T*
F(rawdup) (const array_T *src, size_t cnt)
{
return ooc_array_rawdu p_((void*)src, sizeof(array_T) ,
offsetof(struct T, data), cnt);
}

static inline array_T*
F(resize) (array_T *self, size_t cnt)
{
return ooc_array_resiz e_((void*)self, cnt,
sizeof(array_T) , offsetof(struct T, data), true);
}

static inline array_T*
F(realloc) (array_T *self, size_t cnt)
{
return ooc_array_resiz e_((void*)self, cnt,
sizeof(array_T) , offsetof(struct T, data), false);
}

static inline void
F(del) (array_T *self)
{
if (self)
(ooc_free)(B(se lf));
}

static inline void
F(free) (array_T *self)
{
F(del)(self);
}

static inline size_t
F(cnt) (const array_T *self)
{
return B(self)->cnt;
}

static inline array_T
F(get) (const array_T *self, size_t idx)
{
if (idx >= B(self)->cnt)
ooc_array_badrn g_(__FILE__, __LINE__);

return self[idx];
}

static inline void
F(set) (array_T *self, size_t idx, array_T val)
{
if (idx >= B(self)->cnt)
ooc_array_badrn g_(__FILE__, __LINE__);

self[idx] = val;
}

#undef T
#undef F
#undef B

#endif /* OOC_TYPE_ARRAY_ C */

#undef array_PREFIX
#undef array_T
Aug 9 '06 #7
ja*****@gmail.c om said:

<snip>
>
I use macros because it is posible to typecast easily and
transparently,
Why on earth would you need to "typecast"? It's only an array, for pity's
sake!
and also because they are fast.
Macros don't have a speed. They are completely replaced by the time the
preprocessing is done.

I suggest you take a careful note of the following diagnostic messages which
gcc produces:

foo.c:46: warning: ANSI C forbids braced-groups within expressions
foo.c:47: warning: initialization discards qualifiers from pointer target
type
foo.c:48: warning: ANSI C forbids braced-groups within expressions
foo.c:49: warning: ANSI C forbids braced-groups within expressions
foo.c:50: warning: assignment discards qualifiers from pointer target type
Having error check is against the original intention of being fast.
In which case you can make it a lot faster like this:

int main(void)
{
return 0;
}

If it doesn't have to get the answer right, it can be very quick indeed.
With current computers, being able to allocate 4Gb or more of memory,
there is no need for such comprobations in most situations.
And if every program on your computer assumes it can get 4GB?
Elsewhere,
if a program using dinamic arrays gets out of memory, the system itself
will halt down de application,
Your users might appreciate it if the program at least /tried/ to save their
data for them before halting.
so I don't agree that a memory check
would be necesary here.
I don't agree that your code would be necessary here.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Aug 9 '06 #8
ja*****@gmail.c om said:
pemo wrote:
>On my system, Object *obj = lNEW(Object); expands to ...

Object *obj = ({ int list = (int)malloc( (sizeof(Object) *12) +
(sizeof(int)*3 )); *list++=sizeof( Object); *list++=12; *list++=0;
(Object*)lis t; });

Where should one start - the parenthesied compound statement used in the
assignment perhaps?

Bassically, what it does is to allocate a cache of objects
You misunderstand; pemo is saying that the code is not legal C. And he's
right.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Aug 9 '06 #9
ja*****@gmail.c om wrote:
pemo wrote:
>On my system, Object *obj = lNEW(Object); expands to ...

Object *obj = ({ int list = (int)malloc( (sizeof(Object) *12) +
(sizeof(int)*3 )); *list++=sizeof( Object); *list++=12; *list++=0;
(Object*)lis t; });

Where should one start - the parenthesied compound statement used in the
assignment perhaps?

Bassically, what it does is to allocate a cache of objects (12 is its
<snip>

No it doesn't. It causes the compiler to emit a diagnostic. On many
systems the diagnostic is an error message and no program is produced.
Basically, ({}) is a GNU extension and *not* standard C, it is also not
implemented on a lot of other compilers. In addition, we talk about C
here, not the GNU extensions to C.
--
Flash Gordon
Still sigless on this computer.
Aug 9 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
3039
by: dddddd | last post by:
i need do create simple dinamic site - built mainly of pictures(they are the only dinamic part). pictuers differ by the -Location- and by -Time- (in which they were taken)... so on the index page visitor should have 2 choices (how the pictures will be arranged) (1) by time (2) by location the webmaster will only copy the pictures in folder
3
2537
by: Jose Garcia | last post by:
Hi there, Can somebody explain me how can i use matrixes with dinamic memory? I use malloc and free (NOT new & delete). I want to access to the matrix like Matrix but i don't know how to do that with pointers and malloc & free... If I declare 4 statics matrixs of 576x720, the program brokes down (how is it posible!?), so i must use dinamic memory (i suppose)...
6
2044
by: gp | last post by:
Hi all, I'm using Microsoft Visual C++ 6.0, I would like to see, debugging my project, all the elements of my dinamic objects.... I have a dinamic array and a STL vector and I need to know the fields values at a specific position, but in the Watch windows I can only see the first element...
7
5557
by: Morgan | last post by:
I have read much posts on the argument but no one clearly says if this operation is possible or not. Simply I have a routine which reads from a text file some integer arrays (1 or 2D). The first array in the file has known dimension, but it contains the dimensions (so unknown at compile time) of all the other arrays. So I can allocate memory only after reading the
20
9190
by: GS | last post by:
The stdint.h header definition mentions five integer categories, 1) exact width, eg., int32_t 2) at least as wide as, eg., int_least32_t 3) as fast as possible but at least as wide as, eg., int_fast32_t 4) integer capable of holding a pointer, intptr_t 5) widest integer in the implementation, intmax_t Is there a valid motivation for having both int_least and int_fast?
17
4678
by: Chad Myers | last post by:
I've been perf testing an application of mine and I've noticed that there are a lot (and I mean A LOT -- megabytes and megabytes of 'em) System.String instances being created. I've done some analysis and I'm led to believe (but can't yet quantitatively establish as fact) that the two basic culprits are a lot of calls to: 1.) if( someString.ToLower() == "somestring" ) and
3
1915
by: jesper | last post by:
I would like some feedback on this. A while back I was trying my hand at some pathfinding for a small game I was making. I did not know anything about it so I read some stuff and came up with the code below. I was at the time quite satisfied with it, but reading stuff here has made me doubt it. Is this implementation valid? Is this implementation fast? The member TNode * Spread; I put it in there to
3
2041
by: Chifo | last post by:
hello. i have a problem with a populate html table with data from table here it's the problem two querys retrieving data from table, one of querys show me a colletion of data from 6:00 am to 15:30 pm timestampz, i put this on a part of html table. when time on my if condition es great than 15:31, showme data from 15:31 to 23:59 timestamp and populate another part of html table. but, data in html first part,it's gone away.
25
6510
by: stararic | last post by:
hi, I'm writing a program a kind of calculator that should work with very big numbers (thousand of digits). So, numbers are rappresented by a struct that contains a pointer to integer, e 2 int for dimension of the array e number of digits. the pointer is than used for the malloc of the array... my 2 problems are: 1)some time, when I use my exp function I get the error: *** glibc detected *** ./a.out: free(): invalid size: 0x0975a328...
0
9825
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
1
10595
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10254
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9379
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7793
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5650
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
4458
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
4021
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3116
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.