Beej’s Guide to Network Programming

December 6, 2008

Beej’s Guide to Network Programming

Using Internet Sockets

Version 1.5.3 (01-Nov-1997)

[http://www.ecst.csuchico.edu/~beej/guide/net]


Home

Programming

Net technology

Unixes

Security

RFC, HOWTO

Web technology

Data bases

Other docs


Intro

Hey! Socket programming got you down? Is this stuff just a little too
difficult to figure out from the man pages? You want to do
cool Internet programming, but you don’t have time to wade through a gob
of structs trying to figure out if you have to call
bind() before you connect(), etc., etc.

Well, guess what! I’ve already done this nasty business, and I’m dying
to share the information with everyone! You’ve come to the right place.
This document should give the average competent C programmer the edge
s/he needs to get a grip on this networking noise.


Audience

This document has been written as a tutorial, not a reference. It is
probably at its best when read by individuals who are just starting out
with socket programming and are looking for a foothold. It is certainly
not the complete guide to sockets programming, by any means.

Hopefully, though, it’ll be just enough for those man pages to start
making sense…🙂


Platform and Compiler

Most of the code contained within this document was compiled on a Linux
PC using Gnu’s gcc compiler. It was also found to compile on
HPUX using gcc. Note that every code snippet was not
individually tested.


Contents:


What is a socket?

You hear talk of “sockets” all the time, and perhaps you are wondering just
what they are exactly. Well, they’re this: a way to speak to
other programs using standard Unix file descriptors.

What?

Ok–you may have heard some Unix hacker state, “Jeez,
everything in Unix is a file!” What that person may have been
talking about is the fact that when Unix programs do any sort of I/O,
they do it by reading or writing to a file descriptor. A file
descriptor is simply an integer associated with an open file. But (and
here’s the catch), that file can be a network connection, a FIFO, a
pipe, a terminal, a real on-the-disk file, or just about anything else.
Everything in Unix is a file! So when you want to communicate
with another program over the Internet you’re gonna do it through a file
descriptor, you’d better believe it.

“Where do I get this file descriptor for network communication, Mr.
Smarty-Pants?” is probably the last question on your mind right now, but
I’m going to answer it anyway: You make a call to the socket()
system routine. It returns the socket descriptor, and you communicate
through it using the specialized send() and recv()
(“man send“, “ href="man.cgi?recv">man recv") socket calls."But, hey!" you might be exclaiming right about now. "If it's a file
descriptor, why in the hell can't I just use the normal read()
and write() calls to communicate through the socket?" The short
answer is, "You can!" The longer answer is, "You can, but
send() and recv() offer much greater control over your
data transmission."

What next? How about this: there are all kinds of sockets. There
are DARPA Internet addresses (Internet Sockets), path names on a local
node (Unix Sockets), CCITT X.25 addresses (X.25 Sockets that you can
safely ignore), and probably many others depending on which Unix flavor
you run. This document deals only with the first: Internet Sockets.


Two Types of Internet Sockets

What's this? There are two types of Internet sockets? Yes. Well, no.
I'm lying. There are more, but I didn't want to scare you. I'm only
going to talk about two types here. Except for this sentence, where I'm
going to tell you that "Raw Sockets" are also very powerful and you
should look them up.

All right, already. What are the two types? One is "Stream Sockets";
the other is "Datagram Sockets", which may hereafter be referred to as
"SOCK_STREAM" and "SOCK_DGRAM", respectively.
Datagram sockets are sometimes called "connectionless sockets" (though
they can be connect()'d if you really want. See href="#connect">connect(), below.Stream sockets are reliable two-way connected communication streams.
If you output two items into the socket in the order "1, 2", they will
arrive in the order "1, 2" at the opposite end. They will also be error
free. Any errors you do encounter are figments of your own deranged
mind, and are not to be discussed here.

What uses stream sockets? Well, you may have heard of the
telnet application, yes? It uses stream sockets. All the
characters you type need to arrive in the same order you type them,
right? Also, WWW browsers use the HTTP protocol which uses stream
sockets to get pages. Indeed, if you telnet to a WWW site on port 80,
and type "GET pagename", it'll dump the HTML back at you!

How do stream sockets achieve this high level of data transmission
quality? They use a protocol called "The Transmission Control
Protocol", otherwise known as "TCP" (see
href="ftp://nic.ddn.mil/rfc/rfc793.txt">RFC-793 for extremely detailed
info on TCP.) TCP makes sure your data arrives sequentially and
error-free. You may have heard "TCP" before as the better half of
"TCP/IP" where "IP" stands for "Internet Protocol" (see
href="ftp://nic.ddn.mil/rfc/rfc791.txt">RFC-791.) IP deals with
Internet routing only.Cool. What about Datagram sockets? Why are they called
connectionless? What is the deal, here, anyway? Why are they
unreliable? Well, here are some facts: if you send a datagram, it may
arrive. It may arrive out of order. If it arrives, the data within
the packet will be error-free.

Datagram sockets also use IP for routing, but they don't use TCP;
they use the "User Datagram Protocol", or "UDP" (see
href="ftp://nic.ddn.mil/rfc/rfc768.txt">RFC-768.)Why are they connectionless? Well, basically, it's because you don't
have to maintain an open connection as you do with stream sockets. You
just build a packet, slap an IP header on it with destination
information, and send it out. No connection needed. They are generally
used for packet-by-packet transfers of information. Sample
applications: tftp, bootp, etc.

"Enough!" you may scream. "How do these programs even work if datagrams
might get lost?!" Well, my human friend, each has it's own protocol on
top of UDP. For example, the tftp protocol says that for each packet
that gets sent, the recipient has to send back a packet that says, "I
got it!" (an "ACK" packet.) If the sender of the original packet gets
no reply in, say, five seconds, he'll re-transmit the packet until he
finally gets an ACK. This acknowledgment procedure is very important
when implementing SOCK_DGRAM applications.


Low level Nonsense and Network Theory

Since I just mentioned layering of protocols, it's time to talk about
how networks really work, and to show some examples of how
SOCK_DGRAM
packets are built. Practically, you can probably skip this section.
It's good background, however.

Hey, kids, it's time to learn about Data Encapsulation!
This is very very important. It's so important that you might just
learn about it if you take the networks course here at Chico State😉.
Basically, it says this: a packet is born, the packet is wrapped
("encapsulated") in a header (and maybe footer) by the first protocol
(say, the TFTP protocol), then the whole thing (TFTP header included) is
encapsulated again by the next protocol (say, UDP), then again by the
next (IP), then again by the final protocol on the hardware (physical)
layer (say, Ethernet).

When another computer receives the packet, the hardware strips the
Ethernet header, the kernel strips the IP and UDP headers, the TFTP
program strips the TFTP header, and it finally has the data.

Now I can finally talk about the infamous Layered Network Model.
This Network Model describes a system of network functionality that has
many advantages over other models. For instance, you can write sockets
programs that are exactly the same without caring how the data is
physically transmitted (serial, thin Ethernet, AUI, whatever) because
programs on lower levels deal with it for you. The actual network
hardware and topology is transparent to the socket programmer.

Without any further ado, I'll present the layers of the full-blown
model. Remember this for network class exams:

  • Application
  • Presentation
  • Session
  • Transport
  • Network
  • Data Link
  • Physical

The Physical Layer is the hardware (serial, Ethernet, etc.). The
Application Layer is just about as far from the physical layer as you
can imagine--it's the place where users interact with the network.

Now, this model is so general you could probably use it as an automobile
repair guide if you really wanted to. A layered model more consistent
with Unix might be:

  • Application Layer (telnet, ftp, etc.)
  • Host-to-Host Transport Layer (TCP, UDP)
  • Internet Layer (IP and routing)
  • Network Access Layer (was Network, Data Link, and Physical)

At this point in time, you can probably see how these layers correspond
to the encapsulation of the original data.

See how much work there is in building a simple packet? Jeez! And you
have to type in the packet headers yourself using "cat"! Just
kidding. All you have to do for stream sockets is send() the
data out. All you have to do for datagram sockets is encapsulate the
packet in the method of your choosing and sendto() it out. The
kernel builds the Transport Layer and Internet Layer on for you and the
hardware does the Network Access Layer. Ah, modern technology.

So ends our brief foray into network theory. Oh yes, I forgot to tell
you everything I wanted to say about routing: nothing! That's right,
I'm not going to talk about it at all. The router strips the packet to
the IP header, consults its routing table, blah blah blah. Check out the href="ftp://nic.ddn.mil/rfc/rfc791.txt">IP RFC if you really really
care. If you never learn about it, well, you'll live.


structs

Well, we're finally here. It's time to talk about programming. In this
section, I'll cover various data types used by the sockets interface,
since some of them are a real bitch to figure out.

First the easy one: a socket descriptor. A socket descriptor is the
following type:

    int

Just a regular int.

Things get weird from here, so just read through and bear with me. Know
this: there are two byte orderings: most significant byte (sometimes
called an "octet") first, or least significant byte first. The former
is called "Network Byte Order". Some machines store their numbers
internally in Network Byte Order, some don't. When I say something has
to be in NBO, you have to call a function (such as htons()) to
change it from "Host Byte Order". If I don't say "NBO", then you must
leave the value in Host Byte Order.

My First Struct(TM)--struct sockaddr. This
structure holds socket address information for many types of sockets:

struct sockaddr {
unsigned shortsa_family;/* address family, AF_xxx   */
char  sa_data[14];  /* 14 bytes of protocol address */
};

sa_family can be a variety of things, but it'll be
"AF_INET" for everything we do in this document.
sa_data contains a destination address and port number for the
socket. This is rather unwieldy.

To deal with struct sockaddr, programmers
created a parallel structure: struct sockaddr_in
("in" for "Internet".)

struct sockaddr_in {
short int  sin_family;  /* Address family   */
unsigned short int sin_port;/* Port number  */
struct in_addr sin_addr;/* Internet address */
unsigned char  sin_zero[8]; /* Same size as struct sockaddr */
};

This structure makes it easy to reference elements of the socket
address. Note that sin_zero (which is included to pad the
structure to the length of a struct sockaddr)
should be set to all zeros with the function bzero() or
memset(). Also, and this is the important bit, a
pointer to a struct sockaddr_in can be cast to a
pointer to a struct sockaddr and vice-versa. So
even though socket() wants a struct sockaddr
*
, you can still use a struct
sockaddr_in
and cast it at the last minute! Also, notice
that sin_family corresponds to sa_family in a
struct sockaddr and should be set to
"AF_INET". Finally, the sin_port and
sin_addr must be in Network Byte Order!

"But," you object, "how can the entire structure, struct in_addr
sin_addr
, be in Network Byte Order?" This question requires
careful
examination of the structure struct in_addr, one of the worst
unions alive:

/* Internet address (a structure for historical reasons) */
struct in_addr {
unsigned long s_addr;
};

Well, it used to be a union, but now those days seem to be gone. Good
riddance. So if you have declared "ina" to be of type
struct sockaddr_in, then "ina.sin_addr.s_addr"
references the 4 byte IP address (in Network Byte Order). Note that
even if your system still uses the God-awful union for struct
in_addr
, you can still reference the 4 byte IP address in exactly
the same way as I did above (this due to #defines.)


Convert the Natives!

We've now been lead right into the next section. There's been too much
talk about this Network to Host Byte Order conversion--now is the time
for action!

All righty. There are two types that you can convert: short
(two bytes) and long (four bytes). These functions work for the
unsigned variations as well. Say you want to convert a
short from Host Byte Order to Network Byte Order. Start with
"h" for "host", follow it with "to", then "n" for "network", and "s" for
"short": h-to-n-s, or htons() (read: "Host to Network Short").

It's almost too easy...

You can use every combination if "n", "h", "s", and "l" you want, not
counting the really stupid ones. For example, there is NOT a
stolh() ("Short to Long Host") function--not at this party,
anyway. But there are:

  • htons()--"Host to Network Short"
  • htonl()--"Host to Network Long"
  • ntohs()--"Network to Host Short"
  • ntohl()--"Network to Host Long"

Now, you may think you're wising up to this. You might think, "What do
I do if I have to change byte order on a char?" Then you might
think, "Uh, never mind." You might also think that since your 68000
machine already uses network byte order, you don't have to call
htonl() on your IP addresses. You would be right, BUT if you
try to port to a machine that has reverse network byte order, your
program will fail. Be portable! This is a Unix world! Remember: put
your bytes in Network Order before you put them on the network.

A final point: why do sin_addr and sin_port need to be
in Network Byte Order in a struct sockaddr_in, but
sin_family does not? The answer: sin_addr and
sin_port get encapsulated in the packet at the IP and UDP
layers, respectively. Thus, they must be in Network Byte Order.
However, the sin_family field is only used by the kernel to
determine what type of address the structure contains, so it must be in
Host Byte Order. Also, since
sin_family does not get sent out on the network, it can
be in Host Byte Order.


IP Addresses and How to Deal With Them

Fortunately for you, there are a bunch of functions that allow you to
manipulate IP addresses. No need to figure them out by hand and stuff
them in a long with the << operator.

First, let's say you have a struct sockaddr_in
ina
, and you have an IP address "132.241.5.10" that you want
to store into it. The function you want to use, inet_addr(),
converts an IP address in numbers-and-dots notation into an unsigned
long. The assignment can be made as follows:

ina.sin_addr.s_addr = inet_addr("132.241.5.10");

Notice that inet_addr() returns the address in Network Byte
Order already--you don't have to call htonl(). Swell!

Now, the above code snippet isn't very robust because there is no error
checking. See, inet_addr() returns -1 on error.
Remember binary numbers? (unsigned)-1 just happens to
correspond to the IP address 255.255.255.255! That's the broadcast
address! Wrongo. Remember to do your error checking properly.

All right, now you can convert string IP addresses to longs.
What about the other way around? What if you have a struct
in_addr
and you want to print it in numbers-and-dots
notation? In this case, you'll want to use the function
inet_ntoa() ("ntoa" means "network to ascii") like this:

printf("%s",inet_ntoa(ina.sin_addr));

That will print the IP address. Note that inet_ntoa() takes a
struct in_addr as an argument, not a
long. Also notice that it returns a pointer to a char. This
points to a statically stored char array within inet_ntoa() so
that each time you call inet_ntoa() it will overwrite the last
IP address you asked for. For example:

char *a1, *a2;
.
.
a1 = inet_ntoa(ina1.sin_addr);  /* this is 198.92.129.1 */
a2 = inet_ntoa(ina2.sin_addr);  /* this is 132.241.5.10 */
printf("address 1: %s\n",a1);
printf("address 2: %s\n",a2);

will print:

address 1: 132.241.5.10
address 2: 132.241.5.10

If you need to save the address, strcpy() it to your own
character array.

That's all on this topic for now. Later, you'll learn to convert a
string like "whitehouse.gov" into its corresponding IP address (see href="#dns">DNS, below.)


socket()--Get the File Descriptor!

I guess I can put it off no longer--I have to talk about the
socket() system call. Here's the breakdown:

#include <sys/types.h>
#include <sys/socket.h> 

int socket(int domain, int type, int protocol);

But what are these arguments? First, domain should be set to
"AF_INET", just like in the struct
sockaddr_in
(above.) Next, the type argument tells
the kernel what kind of socket this is: SOCK_STREAM or
SOCK_DGRAM. Finally, just set protocol to
"0". (Notes: there are many more domains than I've
listed. There are many more types than I've listed. See the
socket() man page. Also, there's
a "better" way to get the protocol. See the href="man.cgi?getprotobyname">getprotobyname() man page.)socket() simply returns to you a socket descriptor that you can
use in later system calls, or -1 on error. The global variable
errno is set to the error's value (see the
href="man.cgi?perror">perror() man page.)


bind()--What port am I on?

Once you have a socket, you might have to associate that socket with a
port on your local machine. (This is commonly done if you're going to
listen() for incoming connections on a specific port--MUDs do
this when they tell you to "telnet to x.y.z port 6969".) If you're going to
only be doing a connect(), this may be unnecessary. Read it
anyway, just for kicks.

Here is the synopsis for the bind() system call:

#include <sys/types.h>
#include <sys/socket.h> 

int bind(int sockfd, struct sockaddr *my_addr, int addrlen);

sockfd is the socket file descriptor returned by
socket(). my_addr is a pointer to a struct
sockaddr
that contains information about your address,
namely, port and IP address. addrlen can be set to
sizeof(struct sockaddr).

Whew. That's a bit to absorb in one chunk. Let's have an example:

#include <string.h>
#include <sys/types.h>
#include <sys/socket.h> 

#define MYPORT 3490

main()
{
int sockfd;
struct sockaddr_in my_addr;

sockfd = socket(AF_INET, SOCK_STREAM, 0);
/* do some error checking! */

my_addr.sin_family = AF_INET;
/* host byte order */
my_addr.sin_port = htons(MYPORT);
/* short, network byte order */
my_addr.sin_addr.s_addr = inet_addr("132.241.5.10");
bzero(&(my_addr.sin_zero), 8);
/* zero the rest of the struct */

/* don't forget your error checking for bind(): */
bind(sockfd, (struct sockaddr *)&my_addr,
 sizeof(struct sockaddr));
.
.
.

There are a few things to notice here. my_addr.sin_port is in
Network Byte Order. So is my_addr.sin_addr.s_addr. Another thing to
watch out for is that the header files might differ from system to
system. To be sure, you should check your local man pages.

Lastly, on the topic of bind(), I should mention that some of
the process of getting your own IP address and/or port can can be automated:

my_addr.sin_port = 0; /* choose an unused port at random */
my_addr.sin_addr.s_addr = INADDR_ANY;  /* use my IP address */

See, by setting my_addr.sin_port to zero, you are telling
bind() to choose the port for you. Likewise, by setting
my_addr.sin_addr.s_addr to INADDR_ANY, you are telling it to
automatically fill in the IP address of the machine the process is
running on.

If you are into noticing little things, you might have seen that I
didn't put INADDR_ANY into Network Byte Order! Naughty me.
However, I have inside info: INADDR_ANY is really zero! Zero
still has zero on bits even if you rearrange the bytes. However,
purists will point out that there could be a parallel dimension where
INADDR_ANY is, say, 12 and that my code won't work there.
That's ok with me:

my_addr.sin_port = htons(0); /* choose an unused port at random */
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);  /* use my IP address */

Now we're so portable you probably wouldn't believe it. I just wanted
to point that out, since most of the code you come across won't bother
running INADDR_ANY through htonl().

bind() also returns -1 on error and sets
errno to the error's value.

Another thing to watch out for when calling bind(): don't go
underboard with your port numbers. All ports below 1024 are RESERVED!
You can have any port number above that, right up to 65535 (provided
they aren't already being used by another program.)

One small extra final note about bind(): there are times when
you won't absolutely have to call it. If you are connect()'ing
to a remote machine and you don't care what your local port is (as is
the case with telnet), you can simply call connect(),
it'll check to see if the socket is unbound, and will bind() it
to an unused local port.


connect()--Hey, you!

Let's just pretend for a few minutes that you're a telnet application.
Your user commands you (just like in the movie TRON) to get a
socket file descriptor. You comply and call socket(). Next,
the user tells you to connect to "132.241.5.10" on port "23" (the
standard telnet port.) Oh my God! What do you do now?

Lucky for you, program, you're now perusing the section on
connect()--how to connect to a remote host. You read furiously
onward, not wanting to disappoint your user...

The connect() call is as follows:

#include <sys/types.h>
#include <sys/socket.h> 

int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);

sockfd is our friendly neighborhood socket file descriptor, as
returned by the socket() call, serv_addr is a
struct sockaddr containing the destination port
and IP address, and addrlen can be set to
sizeof(struct sockaddr).

Isn't this starting to make more sense? Let's have an example:

#include <string.h>
#include <sys/types.h>
#include <sys/socket.h> 

#define DEST_IP   "132.241.5.10"
#define DEST_PORT 23

main()
{
int sockfd;
struct sockaddr_in dest_addr;
/* will hold the destination addr */

sockfd = socket(AF_INET, SOCK_STREAM, 0);
/* do some error checking! */

dest_addr.sin_family = AF_INET;/* host byte order */
dest_addr.sin_port = htons(DEST_PORT);
/* short, network byte order */
dest_addr.sin_addr.s_addr = inet_addr(DEST_IP);
bzero(&(dest_addr.sin_zero), 8);
/* zero the rest of the struct */

/* don't forget to error check the connect()! */
connect(sockfd, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr));
.
.
.

Again, be sure to check the return value from
connect()--it'll return -1 on error and set the
variable errno.

Also, notice that we didn't call bind(). Basically, we don't
care about our local port number; we only care where we're going. The
kernel will choose a local port for us, and the site we connect to will
automatically get this information from us. No worries.


listen()--Will somebody please call me?

Ok, time for a change of pace. What if you don't want to connect to a
remote host. Say, just for kicks, that you want to wait for incoming
connections and handle them in some way. The process is two step: first
you listen(), then you accept() (see below.)

The listen call is fairly simple, but requires a bit of explanation:

int listen(int sockfd, int backlog);

sockfd is the usual socket file descriptor from the
socket() system call. backlog is the number of
connections allowed on the incoming queue. What does that mean? Well,
incoming connections are going to wait in this queue until you
accept() them (see below) and this is the limit on how many can
queue up. Most systems silently limit this number to about 20; you can
probably get away with setting it to 5 or 10.

Again, as per usual, listen() returns -1 and sets
errno on error.

Well, as you can probably imagine, we need to call bind() before we call
listen() or the kernel will have us listening on a random port.
Bleah! So if you're going to be listening for incoming connections, the
sequence of system calls you'll make is:

socket();
bind();
listen();
/* accept() goes here */

I'll just leave that in the place of sample code, since it's fairly
self-explanatory. (The code in the accept() section, below, is
more complete.) The really tricky part of this whole sha-bang is the
call to accept().


accept()--"Thank you for calling port 3490."

Get ready--the accept() call is kinda weird! What's going to
happen is this: someone far far away will try to connect() to
your machine on a port that you are listen()'ing on. Their
connection will be queued up waiting to be accept()'ed. You
call accept() and you tell it to get the pending connection.
It'll return to you a brand new socket file
descriptor
to use for this single connection! That's right, suddenly
you have two socket file descriptors for the price of one! The
original one is still listening on your port and the newly created one
is finally ready to send() and recv(). We're there!

The call is as follows:

 #include <sys/socket.h> 

 int accept(int sockfd, void *addr, int *addrlen);

sockfd is the listen()'ing socket descriptor. Easy
enough. addr will usually be a pointer to a local struct
sockaddr_in
. This is where the information about the incoming
connection will go (and you can determine which host is calling you from
which port). addrlen is a local integer variable that should
be set to sizeof(struct sockaddr_in) before its
address is passed to accept(). Accept will not put more than
that many bytes into addr. If it puts fewer in, it'll change
the value of addrlen to reflect that.

Guess what? accept() returns -1 and sets
errno if an error occurs. Betcha didn't figure that.

Like before, this is a bunch to absorb in one chunk, so here's a sample code
fragment for your perusal:

#include <string.h>
#include <sys/types.h>
#include <sys/socket.h> 

#define MYPORT 3490
/* the port users will be connecting to */

#define BACKLOG 10
/* how many pending connections queue will hold */

main()
{
int sockfd, new_fd;
/* listen on sock_fd, new connection on new_fd */
struct sockaddr_in my_addr;
/* my address information */
struct sockaddr_in their_addr;
/* connector's address information */
int sin_size;

sockfd = socket(AF_INET, SOCK_STREAM, 0);
/* do some error checking! */

my_addr.sin_family = AF_INET;
/* host byte order */
my_addr.sin_port = htons(MYPORT);
/* short, network byte order */
my_addr.sin_addr.s_addr = INADDR_ANY;
/* auto-fill with my IP */
bzero(&(my_addr.sin_zero), 8);
/* zero the rest of the struct */

/* don't forget your error checking for these calls: */
bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr));

listen(sockfd, BACKLOG);

sin_size = sizeof(struct sockaddr_in);
new_fd = accept(sockfd, &their_addr, &sin_size);
.
.
.

Again, note that we will use the socket descriptor new_fd for
all send() and recv() calls. If you're only getting
one single connection ever, you can close() the original
sockfd in order to prevent more incoming
connections on the same port, if you so desire.


send() and recv()--Talk to me,
baby!

These two functions are for communicating over stream sockets or
connected datagram sockets. If you want to use regular unconnected
datagram sockets, you'll need to see the section on href="#sendtorecv">sendto() and recvfrom(),
below.The send() call:

int send(int sockfd, const void *msg, int len, int flags);

sockfd is the socket descriptor you want to send data to
(whether it's the one returned by socket() or the one you got
with accept().) msg is a pointer to the data you want
to send, and len is the length of that data in bytes. Just set
flags to 0. (See the
href="man.cgi?send">send() man page for more information
concerning flags.)Some sample code might be:

char *msg = "Beej was here!";
int len, bytes_sent;
.
.
len = strlen(msg);
bytes_sent = send(sockfd, msg, len, 0);
.
.
.

send() returns the number of bytes actually sent out--this
might be less than the number you told it to send!
See, sometimes you
tell it to send a whole gob of data and it just can't handle it. It'll
fire off as much of the data as it can, and trust you to send the rest
later. Remember, if the value returned by send() doesn't match
doesn't match the value in len, it's up to you to send the rest
of the string. The good news is this: if the packet is small (less than
1K or so) it will probably manage to send the whole thing all in
one go. Again, -1 is returned on error, and
errno is set to the error number.

The recv() call is similar in many respects:

int recv(int sockfd, void *buf, int len, unsigned int flags);

sockfd is the socket descriptor to read from, buf is
the buffer to read the information into, len is the maximum
length of the buffer, and flags can again be set to 0.
(See the
recv() man page for flag
information.)

recv() returns the number of bytes actually read into the
buffer, or -1 on error (with errno set, accordingly.)

There, that was easy, wasn't it? You can now pass data back and forth
on stream sockets! Whee! You're a Unix Network Programmer!


sendto() and recvfrom()--Talk to me,
DGRAM-style

"This is all fine and dandy," I hear you saying, "but where does this
leave me with unconnected datagram sockets?" No problemo, amigo. We
have just the thing.

Since datagram sockets aren't connected to a remote host, guess which
piece of information we need to give before we send a packet? That's
right! The destination address! Here's the scoop:

int sendto(int sockfd, const void *msg, int len,
 unsigned int flags, const struct sockaddr *to, int tolen);

As you can see, this call is basically the same as the call to
send() with the addition of two other pieces of information.
to is a pointer to a struct sockaddr
(which you'll probably have as a struct
sockaddr_in
and cast it at the last minute) which contains
the destination IP address and port. tolen can simply be set
to sizeof(struct sockaddr).

Just like with send(), sendto() returns the number of
bytes actually sent (which, again, might be less than the number of bytes you
told it to send!), or -1 on error.

Equally similar are recv() and recvfrom(). The
synopsis of recvfrom() is:

int recvfrom(int sockfd, void *buf, int len, unsigned int flags
 struct sockaddr *from, int *fromlen);

Again, this is just like recv() with the addition of a couple
fields. from is a pointer to a local struct
sockaddr
that will be filled with the IP address and port of
the originating machine. fromlen is a pointer to a local
int that should be initialized to sizeof(struct
sockaddr)
. When the function returns, fromlen will
contain the length of the address actually stored in from.

recvfrom() returns the number of bytes received, or
-1 on error (with errno set accordingly.)

Remember, if you connect() a datagram socket, you can then
simply use send() and recv() for all your
transactions. The socket itself is still a datagram socket and the
packets still use UDP, but the socket interface will automatically add
the destination and source information for you.


close() and shutdown()--Get outta my face!

Whew! You've been send()'ing and recv()'ing data all
day long, and you've had it. You're ready to close the connection on
your socket descriptor. This is easy. You can just use the regular
Unix file descriptor close() function:

close(sockfd);

This will prevent any more reads and writes to the socket. Anyone
attempting to read or write the socket on the remote end will receive an
error.

Just in case you want a little more control over how the socket closes,
you can use the shutdown() function. It allows you to cut off
communication in a certain direction, or both ways (just like
close() does.) Synopsis:

int shutdown(int sockfd, int how);

sockfd is the socket file descriptor you want to shutdown, and
how is one of the following:

  • 0 - Further receives are disallowed
  • 1 - Further sends are disallowed
  • 2 - Further sends and receives are disallowed (like
    close())

shutdown() returns 0 on success, and -1 on error (with
errno set accordingly.)

If you deign to use shutdown() on unconnected datagram sockets,
it will simply make the socket unavailable for further send()
and recv() calls (remember that you can use these if you
connect() your datagram socket.)

Nothing to it.


getpeername()--Who are you?

This function is so easy.

It's so easy, I almost didn't give it it's own section. But here it is
anyway.

The function getpeername() will tell you who is at the other end
of a connected stream socket. The synopsis:

#include <sys/socket.h> 

int getpeername(int sockfd, struct sockaddr *addr, int *addrlen);

sockfd is the descriptor of the connected stream socket,
addr is a pointer to a struct sockaddr
(or a struct sockaddr_in) that will hold the
information about the other side of the connection, and addrlen
is a pointer to an int, that should be initialized to
sizeof(struct sockaddr).

The function returns -1 on error and sets errno
accordingly.

Once you have their address, you can use inet_ntoa() or
gethostbyaddr() to print or get more information. No, you
can't get their login name.


gethostname()--Who am I?

Even easier than getpeername() is the function
gethostname(). It returns the name of the computer that your
program is running on. The name can then be used by
gethostbyname(), below, to determine the IP address of your
local machine.

What could be more fun? I could think of a few things, but they don't
pertain to socket programming. Anyway, here's the breakdown:

#include <unistd.h>

int gethostname(char *hostname, size_t size);

The arguments are simple: hostname is a pointer to an array of
chars that will contain the hostname upon the function's return, and
size is the length in bytes of the hostname array.

The function returns 0 on successful completion, and
-1 on error, setting errno as usual.


DNS--You say "whitehouse.gov", I say "198.137.240.100"

In case you don't know what DNS is, it stands for "Domain Name Service".
In a nutshell, you tell it what the human-readable address is for a
site, and it'll give you the IP address (so you can use it with
bind(), connect(), sendto(), or whatever
you need it for.) This way, when someone enters:

$ telnet whitehouse.gov

telnet can find out that it needs to connect() to
"198.137.240.100".

But how does it work? You'll be using the function
gethostbyname():

#include <netdb.h> 

struct hostent *gethostbyname(const char *name);

As you see, it returns a pointer to a struct
hostent
, the layout of which is as follows:

struct hostent {
char*h_name;
char**h_aliases;
int h_addrtype;
int h_length;
char**h_addr_list;
};
#define h_addr h_addr_list[0]

And here are the descriptions of the fields in the struct
hostent
:

  • h_name - Official name of the host.
  • h_aliases - A NULL-terminated array of alternate names for
    the host.
  • h_addrtype - The type of address being returned; usually
    AF_INET.
  • h_length- The length of the address in bytes.
  • h_addr_list - A zero-terminated array of network addresses
    for the host. Host addresses are in Network Byte Order.
  • h_addr - The first address in
    h_addr_list.

gethostbyname() returns a pointer to the filled
struct hostent, or NULL on error. (But
errno is not set--h_errno is set
instead. See herror(), below.)

But how is it used? Sometimes (as we find from reading computer
manuals), just spewing the information at the reader is not enough.
This function is certainly easier to use than it looks.

Here's an example program:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h> 

int main(int argc, char *argv[])
{
struct hostent *h;

if (argc != 2) {
/* error check the command line */
fprintf(stderr,"usage: getip address\n");
exit(1);
}

if ((h=gethostbyname(argv[1])) == NULL) {
/* get the host info */
herror("gethostbyname");
exit(1);
}

printf("Host name  : %s\n", h->h_name);
printf("IP Address :
 %s\n",inet_ntoa(*((struct in_addr *)h->h_addr)));

return 0;
}

With gethostbyname(), you can't use perror() to print
error message (since errno is not used). Instead, call
herror().

It's pretty straightforward. You simply pass the string that contains
the machine name ("whitehouse.gov") to gethostbyname(), and
then grab the information out of the returned struct
hostent
.

The only possible weirdness might be in the printing of the IP address,
above. h->h_addr is a char *, but
inet_ntoa() wants a struct in_addr passed
to it. So I cast h->h_addr to a struct in_addr
*
, then dereference it to get at the data.


Client-Server Background

It's a client-server world, baby. Just about everything on the network
deals with client processes talking to server processes and vice-versa.
Take telnet, for instance. When you connect to a remote host
on port 24 with telnet (the client), a program on that host (called
telnetd, the server) springs to life. It handles the incoming
telnet connection, sets you up with a login prompt, etc.

The exchange of information between client and server is summarized in
Figure 2.

Note that the client-server pair can speak SOCK_STREAM,
SOCK_DGRAM, or anything else (as long as they're speaking the
same thing.) Some good examples of client-server pairs are
telnet/telnetd, ftp/ftpd, or
bootp/bootpd. Every time you use ftp,
there's a remote program, ftpd, that serves you.

Often, there will only be one server on a machine, and that server will
handle multiple clients using fork(). The basic routine is:
server will wait for a connection, accept() it, and
fork() a child process to handle it. This is what our sample
server does in the next section.


A Simple Stream Server

All this server does is send the string "Hello, World!\n" out
over a stream connection. All you need to do to test this server is run
it in one window, and telnet to it from another with:

$ telnet remotehostname 3490

where remotehostname is the name of the machine you're running
it on.

The server code: (Note: a trailing backslash on a
line means that the line is continued on the next.)

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h> 

#define MYPORT 3490
/* the port users will be connecting to */

#define BACKLOG 10
/* how many pending connections queue will hold */

main()
{
int sockfd, new_fd;
/* listen on sock_fd, new connection on new_fd */
struct sockaddr_in my_addr;
/* my address information */
struct sockaddr_in their_addr;
/* connector's address information */
int sin_size;

if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}

my_addr.sin_family = AF_INET;
/* host byte order */
my_addr.sin_port = htons(MYPORT);
/* short, network byte order */
my_addr.sin_addr.s_addr = INADDR_ANY;
/* auto-fill with my IP */
bzero(&(my_addr.sin_zero), 8);
/* zero the rest of the struct */

if (bind(sockfd, (struct sockaddr *)&my_addr,
 sizeof(struct sockaddr)) \ == -1) {
perror("bind");
exit(1);
}

if (listen(sockfd, BACKLOG) == -1) {
perror("listen");
exit(1);
}

while(1) {  /* main accept() loop */
sin_size = sizeof(struct sockaddr_in);
if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, \
&sin_size)) == -1) {
perror("accept");
continue;
}
printf("server: got connection from %s\n", \
   inet_ntoa(their_addr.sin_addr));
if (!fork()) { /* this is the child process */
if (send(new_fd, "Hello, world!\n", 14, 0) == -1)
perror("send");
close(new_fd);
exit(0);
}
close(new_fd);  /* parent doesn't need this */

while(waitpid(-1,NULL,WNOHANG) > 0);
/* clean up child processes */
}
}

In case you're curious, I have the code in one big
main() function for (I feel) syntactic clarity. Feel free to
split it into smaller functions if it makes you feel better.

You can also get the string from this server by using the client listed
in the next section.


A Simple Stream Client

This guy's even easier than the server. All this client does is connect
to the host you specify on the command line, port 3490. It gets the
string that the server sends.

The client source:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h> 

#define PORT 3490
/* the port client will be connecting to */

#define MAXDATASIZE 100
/* max number of bytes we can get at once */

int main(int argc, char *argv[])
{
int sockfd, numbytes;
char buf[MAXDATASIZE];
struct hostent *he;
struct sockaddr_in their_addr;
/* connector's address information */

if (argc != 2) {
fprintf(stderr,"usage: client hostname\n");
exit(1);
}

if ((he=gethostbyname(argv[1])) == NULL) {
/* get the host info */
herror("gethostbyname");
exit(1);
}

if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}

their_addr.sin_family = AF_INET;
/* host byte order */
their_addr.sin_port = htons(PORT);
/* short, network byte order */
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
bzero(&(their_addr.sin_zero), 8);
/* zero the rest of the struct */

if (connect(sockfd, (struct sockaddr *)&their_addr, \
  sizeof(struct sockaddr)) == -1) {
perror("connect");
exit(1);
}

if ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) == -1) {
perror("recv");
exit(1);
}

buf[numbytes] = '';

printf("Received: %s",buf);

close(sockfd);

return 0;
}

Notice that if you don't run the server before you run the client,
connect() returns "Connection refused". Very useful.


Datagram Sockets

I really don't have that much to talk about here, so I'll just present a
couple of sample programs: talker.c and listener.c.

listener sits on a machine waiting for an incoming packet on
port 4950. talker sends a packet to that port, on the
specified machine, that contains whatever the user enters on the command
line.

Here is the source for listener.c:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h> 

#define MYPORT 4950/* the port users will be connecting to */

#define MAXBUFLEN 100

main()
{
int sockfd;
struct sockaddr_in my_addr;/* my address information */
struct sockaddr_in their_addr;
/* connector's address information */
int addr_len, numbytes;
char buf[MAXBUFLEN];

if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
perror("socket");
exit(1);
}

my_addr.sin_family = AF_INET;
/* host byte order */
my_addr.sin_port = htons(MYPORT);
/* short, network byte order */
my_addr.sin_addr.s_addr = INADDR_ANY;
/* auto-fill with my IP */
bzero(&(my_addr.sin_zero), 8);
/* zero the rest of the struct */

if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) \
   == -1) {
perror("bind");
exit(1);
}

addr_len = sizeof(struct sockaddr);
if ((numbytes=recvfrom(sockfd, buf, MAXBUFLEN, 0, \
   (struct sockaddr *)&their_addr, &addr_len)) == -1) {
perror("recvfrom");
exit(1);
}

printf("got packet from %s\n",inet_ntoa(their_addr.sin_addr));
printf("packet is %d bytes long\n",numbytes);
buf[numbytes] = '';
printf("packet contains \"%s\"\n",buf);

close(sockfd);
}

Notice that in our call to socket() we're finally using
SOCK_DGRAM. Also, note that there's no need to
listen() or accept(). This is one
of the perks of using unconnected datagram sockets!

Next comes the source for talker.c:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/wait.h> 

#define MYPORT 4950/* the port users will be connecting to */

int main(int argc, char *argv[])
{
int sockfd;
struct sockaddr_in their_addr; /* connector's address information */
struct hostent *he;
int numbytes;

if (argc != 3) {
fprintf(stderr,"usage: talker hostname message\n");
exit(1);
}

if ((he=gethostbyname(argv[1])) == NULL) {
/* get the host info */
herror("gethostbyname");
exit(1);
}

if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
perror("socket");
exit(1);
}

their_addr.sin_family = AF_INET;
/* host byte order */
their_addr.sin_port = htons(MYPORT);
/* short, network byte order */
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
bzero(&(their_addr.sin_zero), 8);
/* zero the rest of the struct */

if ((numbytes=sendto(sockfd, argv[2], strlen(argv[2]), 0, \
 (struct sockaddr *)&their_addr, sizeof(struct sockaddr))) == -1) {
perror("recvfrom");
exit(1);
}

printf("sent %d bytes
 to %s\n",numbytes,inet_ntoa(their_addr.sin_addr));

close(sockfd);

return 0;
}

And that's all there is to it! Run listener on some machine,
then
run talker on another. Watch them communicate! Fun
G-rated excitement for the entire nuclear family!

Except for one more tiny detail that I've mentioned many times in the
past: connected datagram sockets. I need to talk about this here, since
we're in the datagram section of the document. Let's say that
talker calls connect() and specifies the
listener's address. From that point on, talker may
only sent to and receive from the address specified by
connect(). For this reason, you don't have to use
sendto() and recvfrom(); you can simply use
send() and recv().


Blocking

Blocking. You've heard about it--now what the hell is it? In a
nutshell, "block" is techie jargon for "sleep". You probably noticed
that when you run listener, above, it just sits there until a
packet arrives. What happened is that it called recvfrom(),
there was no data, and so recvfrom() is said to "block" (that
is, sleep there) until some data arrives.

Lots of functions block. accept() blocks. All the
recv*() functions block. The reason they can do this is
because they're allowed to. When you first create the socket descriptor
with socket(), the kernel sets it to blocking. If you don't
want a socket to be blocking, you have to make a call to
fcntl():

#include <unistd.h>
#include <fcntl.h>
.
.
sockfd = socket(AF_INET, SOCK_STREAM, 0);
fcntl(sockfd, F_SETFL, O_NONBLOCK);
.
.

By setting a socket to non-blocking, you can effectively "poll" the
socket for information. If you try to read from a non-blocking socket
and there's no data there, it's not allowed to block--it will return
-1 and errno will be set to EWOULDBLOCK.

Generally speaking, however, this type of polling is a bad idea. If you
put your program in a busy-wait looking for data on the socket, you'll
suck up CPU time like it was going out of style. A more elegant
solution for checking to see if there's data waiting to be read comes in
the following section on select().


select()--Synchronous I/O Multiplexing

This function is somewhat strange, but it's very useful. Take the
following situation: you are a server and you want to listen for
incoming connections as well as keep reading from the connections you
already have.

No problem, you say, just an accept() and a couple of
recv()s. Not so fast, buster! What if you're blocking on an
accept() call? How are you going to recv() data at
the same time? "Use non-blocking sockets!" No way! You don't want to
be a CPU hog. What, then?

select() gives you the power to monitor several sockets at the
same time. It'll tell you which ones are ready for reading, which are
ready for writing, and which sockets have raised exceptions, if you
really want to know that.

Without any further ado, I'll offer the synopsis of select():

   #include <sys/time.h>
   #include <sys/types.h>
   #include <unistd.h> 

   int select(int numfds, fd_set *readfds, fd_set *writefds,
  fd_set *exceptfds, struct timeval *timeout);

The function monitors "sets" of file descriptors; in particular
readfds, writefds, and exceptfds. If you
want to see if you can read from standard input and some socket
descriptor, sockfd, just add the file descriptors 0 and
sockfd to the set readfds. The parameter
numfds should be set to the values of the highest file
descriptor plus one. In this example, it should be set to
sockfd+1, since it is assuredly higher than standard input
(0).

When select() returns, readfds will be modified to
reflect which of the file descriptors you selected is ready for reading.
You can test them with the macro FD_ISSET(), below.

Before progressing much further, I'll talk about how to manipulate these
sets. Each set is of the type fd_set. The following macros
operate on this type:

  • FD_ZERO(fd_set *set) - clears a file descriptor set
  • FD_SET(int fd, fd_set *set) - adds fd to the set
  • FD_CLR(int fd, fd_set *set) - removes fd from the set
  • FD_ISSET(int fd, fd_set *set) - tests to see if fd is in the set

Finally, what is this weirded out struct timeval? Well,
sometimes you don't want to wait forever for someone to send you some
data. Maybe every 96 seconds you want to print "Still Going..." to the
terminal even though nothing has happened. This time structure allows
you to specify a timeout period. If the time is exceeded and
select() still hasn't found any ready file descriptors, it'll
return so you can continue processing.

The struct timeval has the follow fields:

struct timeval {
int tv_sec; /* seconds */
int tv_usec;/* microseconds */
};

Just set tv_sec to the number of seconds to wait, and set
tv_usec to the number of microseconds to wait. Yes, that's
microseconds, not milliseconds. There are 1,000 microseconds in a
millisecond, and 1,000 milliseconds in a second. Thus, there are
1,000,000 microseconds in a second. Why is it "usec"? The "u"
is supposed to look like the Greek letter Mu that we use for "micro".
Also, when the function returns, timeout might be
updated to show the time still remaining. This depends on what flavor
of Unix you're running.

Yay! We have a microsecond resolution timer! Well, don't count on
it. Standard Unix timeslice is 100 milliseconds, so you'll probably
have to wait at least that long, no matter how small you set your
struct timeval.

Other things of interest: If you set the fields in your
struct timeval to 0, select()
will timeout immediately, effectively polling all the file descriptors
in your sets. If you set the parameter timeout to NULL, it
will never timeout, and will wait until the first file descriptor is
ready. Finally, if you don't care about waiting for a certain set, you
can just set it to NULL in the call to select().

The following code snippet waits 2.5 seconds for
something to appear on standard input:

   #include <sys/time.h>
   #include <sys/types.h>
   #include <unistd.h> 

   #define STDIN 0  /* file descriptor for standard input */

   main()
   {
   struct timeval tv;
   fd_set readfds;

   tv.tv_sec = 2;
   tv.tv_usec = 500000;

   FD_ZERO(&readfds);
   FD_SET(STDIN, &readfds);

   /* don't care about writefds and exceptfds: */
   select(STDIN+1, &readfds, NULL, NULL, &tv);

   if (FD_ISSET(STDIN, &readfds))
   printf("A key was pressed!\n");
   else
   printf("Timed out.\n");
   }

If you're on a line buffered terminal, the key you hit should be RETURN
or it will time out anyway.

One final note of interest about select(): if you have a socket
that is listen()'ing, you can check to see if there is a new
connection by putting that socket's file descriptor in the
readfds set.

And that, my friends, is a quick overview of the almighty
select() function.


More References

You've come this far, and now you're screaming for more! Where else can
you go to learn more about all this stuff?

Try the following man pages, for starters:

Also, look up the following href="http://www.clbooks.com/">books:

Internetworking with TCP/IP, volumes I-III by Douglas E. Comer
and David L. Stevens. Published by Prentice Hall. Second
edition ISBNs: 0-13-468505-9, 0-13-472242-6, 0-13-474222-2. There is a
third edition of this set which covers IPv6 and IP over ATM.

Using C on the UNIX System by David A. Curry. Published by
O'Reilly & Associates, Inc. ISBN 0-937175-23-4.

TCP/IP Network Administration by Craig Hunt. Published by
O'Reilly & Associates, Inc. ISBN 0-937175-82-X.

TCP/IP Illustrated, volumes 1-3 by W. Richard Stevens and
Gary R. Wright. Published by Addison Wesley. ISBNs: 0-201-63346-9,
0-201-63354-X, 0-201-63495-3.

Unix Network Programming by W. Richard Stevens. Published by
Prentice Hall. ISBN 0-13-949876-1.

On the web:

BSD Sockets: A Quick And Dirty Primer

(http://sci173x.mrs.umn.edu/~bentlema/unix/sockets.html)

Client-Server
Computing

(http://pandonia.canberra.edu.au/ClientServer/socket.html)


Intro to TCP/IP
(gopher)

(gopher://gopher-chem.ucdavis.edu/11/Index/Internet_aw/Intro_the_Internet/intro.to.ip/)

Internet Protocol Frequently
Asked Questions
(France)

(http://web.cnam.fr/Network/TCP-IP/)

The Unix Socket
FAQ

(http://www.auroraonline.com/sock-faq/)

RFCs--the real dirt:
RFC-768 -- The
User Datagram Protocol (UDP)

(ftp://nic.ddn.mil/rfc/rfc768.txt)

RFC-791 -- The
Internet Protocol (IP)

(ftp://nic.ddn.mil/rfc/rfc791.txt)

RFC-793 -- The
Transmission Control Protocol (TCP)

(ftp://nic.ddn.mil/rfc/rfc793.txt)

RFC-854 -- The
Telnet Protocol

(ftp://nic.ddn.mil/rfc/rfc854.txt)

RFC-951 -- The
Bootstrap Protocol (BOOTP)

(ftp://nic.ddn.mil/rfc/rfc951.txt)

RFC-1350 -- The
Trivial File Transfer Protocol (TFTP)

(ftp://nic.ddn.mil/rfc/rfc1350.txt)


Disclaimer and Call for Help

Well, that's the lot of it. Hopefully at least some of the information
contained within this document has been remotely accurate and I
sincerely hope there aren't any glaring errors. Well, sure, there
always are.

So, if there are, that's tough for you. I'm sorry if any inaccuracies
contained herein have caused you any grief, but you just can't hold me
accountable. See, I don't stand behind a single word of this document,
legally speaking. This is my warning to you: the whole thing could be a
load of crap.

But it's probably not. After all, I've spent many many hours messing
with this stuff, and implemented several TCP/IP network utilities for
Windows (including Telnet) as summer work. I'm not the sockets god; I'm
just some guy.

By the way, if anyone has any constructive (or destructive) criticism
about this document, please send mail to href="mailto:beej@ecst.csuchico.edu">beej@ecst.csuchico.edu and I'll
try to make an effort to set the record straight.In case you're wondering why I did this, well, I did it for the money.
Hah! No, really, I did it because a lot of people have asked me
socket-related questions and when I tell them I've been thinking about
putting together a socket page, they say, "cool!" Besides, I feel that
all this hard-earned knowledge is going to waste if I can't share it
with others. WWW just happens to be the perfect vehicle. I encourage
others to provide similar information whenever possible.

Enough of this--back to coding!😉


Copyright © 1995, 1996 by Brian "Beej" Hall. This guide may be
reprinted in any medium provided that its content is not altered, it is
presented in its entirety, and this copyright notice remains
intact. Contact
href=mailto:beej@ecst.csuchico.edu>beej@ecst.csuchico.edu for more
information.


With any suggestions or questions please feel free to
contact us

Sử dụng Administration Tools Pack quản trị các máy tính từ xa

December 5, 2008
Nếu bạn đã từng sử dụng chức năng Remote Desktop Connection của Windows thì chắc hẳn không lạ gì tác dụng của nó. Lần này Quản Trị Mạng sẽ hướng dẫn bạn cách quản trị từ xa các máy tính sử dụng hệ điều hành Microsoft Windows Server 2003, Microsoft Windows XP hay Microsoft Windows 2000 bằng công cụ Windows Server 2003 Administration Tool Pack (Adminpak). Ngoài ra, chúng tôi còn thảo luận các vấn đề tương thích khác nhau xuất hiện khi bạn quản trị từ xa các máy tính chạy một trong ba hệ điều hành trên, từ cả phía máy người dùng cũng như máy chủ của bạn.

Các chủ đề được thảo luận trong bài này gồm:

  • Các tuỳ chọn quản trị từ xa máy tính chạy hệ điều hành Windows Server 2002, Windows XP và Windows 2000.
  • Địa chỉ download phiên bản đầu tiên (RTM) và Service Pack 1 cho Windows Server 2003 Administration Tools Pack.
  • Các vấn đề cụ thể khi quản trị dòng Windows 64 bit.
  • Các vấn đề tương thích khi máy tính trên nền Windows 2000 Professional sử dụng công cụ quản trị Windows 2000 và nâng cấp lên Windows XP.
  • Các vấn đề tương thích khi bộ điều khiển tên miền trên nền Windows 2000 được nâng cấp lên bộ điều khiển tên miền trong Windows Server 2003.
  • Các vấn đề đã được biết đến khi bạn dùng công cụ quản trị ở phiên bản đầu tiên (RTM) và Service Pack 1 của Windows Server 2003 Administration Tools Pack để quản lý các máy dùng Windows 2000, Windows XP và Windows Server 2003.

Các tuỳ chọn quản trị từ xa

Kinh nghiệm hay nhất cho thấy là máy tính được dùng để thực hiện các nhiệm vụ quản trị phải chạy cùng một hệ điều hành với máy tính đang được quản trị từ xa.

Phương tiện cài đặt Windows Server 2003 và Windows 2000 gồm các công cụ quản trị đồ hoạ và dòng lệnh, có thể được dùng một cách cục bộ và trong hầu hết các trường hợp quản trị từ xa hệ điều hành mức trên cũng như mức dưới với các thành phần bậc cao.

Để quản trị từ xa các máy đang chạy Windows Server 2003 hay Windows 2000 từ các máy dùng Windows Server 2003, Windows XP hay Windows 2000, dùng một trong các phương thức sau:
Cài đặt và dùng các công cụ quản trị đồ hoạ được gói kèm trong Administration Tools Pack để quản trị từ xa máy tính chạy trên nền Windows Server 2003, Windows XP và Windows 2000. Vấn đề thao tác giữa các phần thường xuất hiện trên các hệ điều hành. Chúng thực hiện các nhiệm vụ quản trị trên bàn giao tiếp của máy đích hay trên một máy tính đang chạy cùng một hệ điều hành với máy dùng để quản trị từ xa.

Dùng Terminal Services để quản trị từ xa các máy đã cài đặt cục bộ công cụ quản trị dòng lệnh và giao diện đồ hoạ người dùng (GUI). Để tránh giới hạn hai phiên làm việc, bạn có thể dùng mô hình Application Server để tạo chương trình cài đặt trên nền Windows Server 2003 hoặc Windows 2000 đang chạy Terminal Server hay Terminal Services. Vấn đề thao tác giữa các phần xuất hiện trong các hệ điều hành thực hiện nhiệm vụ quản trị từ một server hỗ trợ Terminal Server hoặc Terminal Services và chạy cùng một hệ điều hành như máy từ xa đang được quản trị.

Dùng các công cụ dòng lệnh (command-line) và các script để quản trị cục bộ và từ xa các máy chạy Windows Server 2003, Windows XP hay Windows 2000. Các công cụ và các bản script này bao gồm Active Directory Service Interfaces (ADSI), Windows Net.exe commands và các công cụ được gói trong Suptools.msi. Vấn đề thao tác giữa các phần xuất hiện trong các hệ điều hành thực hiện nhiệm vụ quản trị trên một console bàn giao tiếp của máy đích hoặc trên một máy chỉ định thực hiện nhiệm vụ quản trị có cùng hệ điều hành với máy ở xa đang được quản trị. Ví dụ các công cụ hỗ trợ (Support Tools) Windows Server 2003 Service Pack 1 (SP1) có thể được cài đặt lên một máy đang chạy Windows XP Professional. Nhưng chúng không được đảm bảo sẽ hoạt động tốt trong bối cảnh như vậy.

Các công cụ thường hay có vấn đề được biết đến gồm:

Dfsutil.exe

Netdiag.exe

Netcap.exe

Ntfrsutil.exe
Nếu bạn muốn dùng các công cụ này trên máy Windows Server 2003 SP1, bạn nên chạy chúng từ một máy đã cài sẵn Windows Server 2003 SP1. Bạn có thể dùng thành phần Remote Desktop để kết nối máy sử dụng Windows Server 2003 SP1 đang chạy Support Tools.

Gói công cụ quản trị Windows Server 2003 và Windows 2000 Server

Để công việc quản lý các gói dịch vụ từ xa của bạn dễ dàng hơn, Microsoft hỗ trợ các công cụ quản trị đồ hoạ trong một file tự nén hiện được dùng rất phổ biến là Adminpak.msi (Adminpack).

Chú ý: Trong các phiên bản 64-bit của Windows Server 2003, file này được gọi là Wadminpak.msi.

Administration Tools Pack (Gói công cụ quản trị) trong Windows 2000 được đặt ở thư mục 1386 trên CD họ Windows 2000 Server và cài đặt trên các máy đang chạy Windows 2000. Phần lớn các công cụ trong Windows 2000 Adminpak đều có thể quản trị từ xa Windows 2000 cũng như các phiên bản 32-bit và 64-bit của Windows XP Professional, các phiên bản 32-bit và 64-bit của Windows Server 2003.

Windows Server 2003 Administration Tools Pack cũng được đặt trong thư mục 1386 của đĩa CD cài Microsoft Windows Server 2003 và bạn hoàn toàn có thể download miễn phí trên website của Microsoft www.microsoft.com. Bảng dưới đây tóm tắt các hệ điều hành bạn có thể cài Adminpak từ Windows 2000, phiên bản đầu tiên của Windows Server 2003 (RTM) hoặc Windows Server 2003 Service Pack 1 (SP1). Ngoài ra bảng này còn tóm tắt các hệ điều hành Adminpak có thể quản trị từ xa.

Để download file cài đặt Adminpak, bạn có thể vào website của Microsoft: http://www.microsoft.com/downloads

Tổng quan về cài đặt và tương thích của Administration Tools Pack Windows Server 2003

Nếu bạn muốn quản trị từ xa các máy thành viên cơ sở sử dụng Windows Server 2003 hoặc Windows 2000 và quản lý các bộ điều khiển tên miền trên client dùng Windows Server 20003 hoặc Windows XP Professional, hãy chú ý các vấn đề cài đặt sau:
Bạn phải gỡ bỏ các phiên bản thử nghiệm beta trước đó của Windows Server 2003 Administration Tools Pack trước khi cài đặt phiên bản chính thức.

Chú ý: Trong một số trường hợp giới hạn, các server (máy chủ) phải được quản trị từ các client (máy khách) có cùng hệ điều hành. Ví dụ, các hoạt động quản trị từ xa trên máy chủ chạy Windows 2000 chỉ có thể thực thi từ máy khách cũng chạy Windows 2000. Tương tự máy chủ chạy Windows Server 2003 cũng chỉ có thể quản trị từ các máy khách chạy Windows Server 2003, máy chủ cài Windows XP thì máy khách quản trị cũng phải là Windows XP. Tài liệu trong bài này mô tả một số giới hạn và hạn chế ở từng công cụ, trong đó có Administration Tools Pack.

Nếu bạn không gỡ Windows Server 2003 RTM Administration Tools Pack (Adminpak.msi) trước khi nâng cấp lên Windows Server 2003 Service Pack 1, việc cài đặt Administration Tools Pack sẽ thất bại. Nếu bạn gỡ Administration Tools Pack bằng chức năng “Add or Remove Programs ” trong Control Panel hoặc bằng cách chạy Adminpak.msi, bạn sẽ nhận được các thông báo lỗi sau:

Thông báo lỗi 1

Windows Server 2003 Administration Tools Pack can only be installed on Windows XP Professional with QFE Q329357 applied, on Windows XP Professional Service Pack 1 or later, or on computers running Windows Server 2003 operating systems.
(Windows Server 2003 Administration Tools Pack chỉ có thể được cài đặt trên Windows XP Professional với ứng dụng QFE Q32957, trên Windows XP Professional Servie Pack 1 hoặc phiên bản mới hơn và trên các máy sử dụng hệ điều hành Windows Server 2003.)

Thông báo lỗi 2

Setup Failed – Due to an error, Windows Server 2003 Administration Tools Pack Setup Wizard was unable to finish.
(Chương trình cài đặt thất bại – Hãy xử lý lỗi, Windows Server 2003 Administration Tools Pack Setup Wizard không thể hoàn tất).

Bạn không thể cài đặt file Windows 2000 Adminpak.msi trên các máy dùng Windows Server 2003 hoặc trên các client (máy khách) dùng Windows XP. Các công cụ này không hoạt động trên các hệ điều hành mới hơn và không hỗ trợ chúng. Bạn nên dùng phiên bản Administration Tools Pack của Windows Server 2003 trên các máy Windows XP.

Windows Server 2003 Administration Tools Pack không thể được cài đặt hay chạy trên các máy dùng Windows 2000. Nếu bạn vẫn cố gắng thực hiện điều đó, bạn sẽ nhận được thông báo lỗi sau:

Windows Server 2003 Administration Tools Pack can only be installed on Windows XP Professional with hotfix Q329357 applied, or on Windows XP Professional SP1 or later, or on computers that are running Windows Server 2003 operating systems.

Service pack level mismatch. Obtain the Administration Tools Pack that matches the service pack level of your operating system.

(Windows Server 2003 Administration Tools Pack chỉ có thể được cài đặt trên Windows XP Professional có áp dụng gói sửa chữa Q32935 hoặc Windows XP Professional SP1 (có thể là SP2, SP3) hoặc trên các máy đang dùng hệ điều hành Windows Server 2003.

Gói dịch vụ không khớp. Administration Tools Pack cần phải khớp với mức gói dịch vụ (Server Pack) của hệ điều hành).

Tương tự, các tiện ích dòng lệnh của Windows Server 2003 Administration Tools Pack được thiết kế chỉ để chạy trên các máy tính dùng Windows XP hoặc Windows Server 2003. Chúng sẽ không hoạt động nếu DLL không khớp hoặc một điểm vào bị lỗi. Điều này sẽ xuất hiện khi bạn copy các tiện ích đó vào máy tính dùng Windows 2000. Nếu bạn cố gắng cài đặt Windows 2000 Administration Tools Pack lên máy dùng Windows Server 2003, bạn sẽ nhận được một thông báo lỗi như sau:

Windows 2000 Administration Tools are incompatible with Windows Server 2003 operating systems. Install Windows Server 2003 Administration Tools Pack.
(Windows 2000 Administration Tools Pack không tương thích với các hệ điều hành Windows Server 2003. Hãy cài Windows Server 2003 Administration Tools Pack).

Windows XP Professional không có file Windows Server 2003 Adminpak.msi vì các công cụ này là một phần của sản phẩm Windows Server 2003 và chỉ gắn liền với hệ điều hành này.

Phiên bản đầu tiên (original-release) của Windows Server 2003 Adminpak.msi chỉ có thể cài đặt trên các máy dùng Windows Server 2003 RTM, Windows XP Professional SP1, hoặc Windows XP Professional SP2.

Nếu bạn đang dùng Windows XP Professional SP2 và Windows Server 2003 Administration Tools Pack, bạn không thể quản trị các dịch vụ Cluster. Nhưng nếu bạn dùng Windows XP Professional SP1 và Windows Server 2003 Administration Tools Pack thì lại hoàn toàn có thể.

Đa số các công cụ quản trị Windows Server 2003 làm việc giống như các thành phần tương ứng trong Windows 2000, chỉ có một số chức năng được nâng cao hơn. Chẳng hạn như chức năng drag-and-drop (kéo và thả) của Windows Server 2003 Users và Computers snap-in bổ sung đầy đủ hơn nhiều so với các bộ điều khiển tên miền của Windows 2000. Nhưng một số công cụ quản trị Windows Server 2003 không được mở hoặc hỗ trợ khi bạn quản trị các máy dùng Windows 2000.

Chẳng hạn một số công cụ quản trị tuỳ thuộc vào chức năng trong Windows Server 2003 như “Saved query for last logon time” không được hỗ trợ trong Windows 2000 Server vì các phiên bản trước đó của server không đòi hỏi phải có server-side. Trong một số trường hợp hiếm, các công cụ quản trị Windows Server 2003 vẫn có thể không tương thích và không được hỗ trợ để quản lý các máy dùng Windows 2000. Tương tự, một số trường hợp các công cụ quản trị Windows 2000 cũng có thể không tương thích với các máy dùng Windows Server 2003.

Nâng cấp các máy dùng Windows 2000 lên Windows Server 2003 hoặc Windows XP

Khi một máy dùng hệ điều hành Windows 2000, đã cài Windows 2000 Adminpak nâng cấp lên Windows Server 2003 hoặc Windows XP, thành phần System Compatibility Report (Báo cáo về tính tương thích hệ thống) được thể hiện. Thành phần này sẽ nói rằng các công cụ quản trị Windows 2000 không tương thích với Windows Server 2003 hoặc Windows XP. Nếu bạn kích vào Details (xem thông tin chi tiết), bạn sẽ nhận được thông báo lỗi sau:

Setup has detected Windows 2000 Administration Tools on your computer. Windows 2000 Administration Tools are incompatible with Windows Server 2003 operating systems. Use one of the following methods:

  • Cancel this upgrade, remove Windows 2000 Administration Tools, and then restart the upgrade.
  • Complete this upgrade, and then immediately install the Windows Server 2003 Administration Tools Pack by running the Adminpak.msi Windows Installer package file. Adminpak.msi is located in the \i386 folder of your Windows Server 2003 CD.

(Chương trình cài đặt đã tìm thấy thành phần Windows 2000 Administration Tools Pack trên máy tính của bạn. Windows 2000 Administration Tools Pack không tương thích với hệ điều hành Windows Server 2003. Sử dụng một trong các phương thức sau:

  • Huỷ bỏ quá trình nâng cấp hiện tại, gỡ Windows 2000 Administration Tools Pack ra khỏi máy và bắt đầu nâng cấp lại.
  • Hoàn chỉnh quá trình nâng cấp này, sau đó lập tức cài đặt Windows Server 2003 Administration Tools Pack bằng cách chạy gói file Adminpak.msi Windows Installer. Adminpak.msi được đặt tại thư mục \i386 trong đĩa CD cài Windows Server 2003.)

Chú ý: Nếu các thành phần quản trị Windows 2000 được gỡ ra khỏi vị trí đang tồn tại khi máy dùng hệ điều hành Windows 2000 nâng cấp lên Windows Server 2003, đừng cố gắng loại bỏ biểu tượng Windows 2000 Administration Tools xuất hiện trong thành phần Add or Remove Programs trong Control Panel.

Nếu bạn cố gắng gỡ bỏ các công cụ quản trị Windows 2000 bằng cách dùng chức năng Add or Remove Programs, có thể bạn sẽ nhận được thông báo lỗi sau:

apphelp dialog cancelled thus preventing the application from starting.
(Hộp thoại trợ giúp ứng dụng đã huỷ bỏ. Do đó các ứng dụng không thể khởi động được).

Bỏ qua thông báo lỗi này. Khi bạn cài Windows Server 2003 Administration Tools Pack, biểu tượng Windows 2000 Administration Tools được thay thế bởi biểu tượng của Windows Server 2003 Administration Tools Pack.

Các chi tiết kỹ thuật cơ bản về Internet

October 17, 2007

Giới thiệu

Internet sử dụng một tập hợp các giao thức mạng được gọi là TCP/IP. Bài viết này chúng tôi muốn miêu tả cho các bạn các giao thức chuẩn (Standard) và các ứng dụng đã được phát triển để hỗ trợ các giao thức này. Các giao thức này cung cấp một phương thức chuẩn cho việc truyền tải các message. Chúng đưa ra các định dạng cho các message và xử lý trong các điều kiện bị lỗi đường truyền xảy ra. Các giao thức này là độc lập với phần cứng của mạng, điều này có nghĩa là nó cho phép truyền thông giữa các mạng khác nhau với các phần cứng khác nhau miễn là chúng sử dụng cùng một kiểu giao thức.

TCP/IP (Transmission Control Protocol/ Internet Protocol)

TCP/IP được sử dụng để truyền thông dễ dàng bên trong một mạng bao gồm nhiều phần cứng khác nhau. Thông tin truyền đi được chia thành các gói (packet) thường là từ 1-1500 ký tự để tránh việc giữ độc quyền của một mạng. TCP là một giao thức mức truyền tải cho phép một quy trình trên một máy tính gửi dữ liệu đến một quá trình xử lý trên máy tính khác. Nó là một giao thức kết nối định hướng (oriented), nghĩa là phải có một đường dẫn được thiết lập giữa hai máy tính. Còn IP đưa ra một biểu đồ, định dạng của dữ liệu tồn tại trong suốt quá trình truyền tải của mạng và thực hiện sự phân phối không kết nối. Sự phân phối không kết nối yêu cầu mỗi biểu đồ phải bao gồm địa chỉ nguồn và địa chỉ đích và mỗi biểu đồ được sử lý một cách tách biệt. TCP lấy thông tin và phân chia nó thành nhiều mẩu nhỏ gọi là các gói, sau đó đánh số các gói và gửi chúng đi.

Bên phía máy nhận, các gói được thu thập lại và xắp xếp lại sao cho đúng thứ tự. Nếu có sự mất mát dữ liệu xảy ra, bên máy nhận sẽ yêu cầu máy gửi phát lại. Gói dữ liệu được gửi bao gồm trong nó là checksum (cách kiểm tra tổng), cách này được sử dụng để kiểm tra các lỗi có thể xuất hiện trong khi truyền dữ liệu. Nếu bên phía máy nhận thấy có lỗi xuất hiện khi tính toán và so sánh checksum. Nó sẽ vứt bỏ gói dữ liệu này và yêu cầu bên máy phát phát lại. Khi mọi thứ được thu nhận một cách đầy đủ, dữ liệu sẽ thể hiện qua ứng dụng thích hợp (ví dụ e-mail).

UDP: User Datagram Protocol

UDP đơn giản hơn TCP. Các khái niệm cơ bản của chúng là như nhau ngoại trừ UDP không liên quan đến các gói dữ liệu bị mất hay giữ đúng thứ tự của chúng. Nó được sử dụng cho các message ngắn. Nếu nó không nhận được một phúc đáp, thì nó sẽ gửi lại yêu cầu cho việc truyền lại toàn bộ dữ liệu. Loại giao thức truyền tải này gọi là giao thức không kết nối.

Internet Addressing

Tất cả các máy tính trên Internet phải có một địa chỉ mạng riêng biệt để có thể truyền thông một cách hiệu quả với các máy tính khác. Cách thức định địa chỉ được sử dụng bên trong Internet là một địa chỉ 32-bit được phân đoạn theo một cấu trúc phân cấp. Địa chỉ IP bao gồm 4 số nhỏ hơn 256 được đặt cách nhau bằng dấu chấm (#.#.#.#). Tại mức thấp nhất, các máy tính truyền thông với các máy tính khác bằng cách sử dụng một địa chỉ phần cứng (trên các LAN, cái này gọi là địa chỉ MAC (Medium Access Control)). Mặc dù vậy, các computer user xử lý ở hai mức cao hơn và có vẻ trừu tượng hơn để giúp các máy hình dung và tính nhận ra mạng. Mức đầu tiên là địa chỉ IP của máy tính (ví dụ: 131.136.196.2) và mức thứ hai là mức con người có thể đọc từ địa chỉ này (ví dụ: manitou.cse.dnd.ca). Cách định địa chỉ này nhìn chung là ít được sử dụng. ARP (Address Resolution Protocol) có thể được sử dụng bằng máy tính để phân tích các địa chỉ IP thành các địa chỉ phần cứng tương ứng.

Các kiểu kết nối và các bộ kết nối

Có hai loại máy tính được nối vào Internet đó là: các server và các client. Các Server (hay còn gọi là máy chủ) có thể được hiểu như một người cung cấp thông tin. Bao gồm trong nó là tài nguyên và dữ liệu có sẵn cho các máy khác trên mạng có thể truy cập và sử dụng. Còn loại thứ hai được kết nối đến Internet là các client (hay còn gọi là máy khách), nó được hiểu như một người lấy thông tin. Các máy khách sẽ truy cập vào mạng và lấy tài nguyên và dữ liệu được đặt ở máy chủ mà sẽ không cung cấp bất cứ tài nguyên nào tới máy chủ.

Cả máy chủ và máy khách đều có thể được kết nối tới Internet với các phương pháp khác nhau, các phương pháp khác nhau này đưa ra các khả năng truyền thông khác nhau phụ thuộc vào sự quá tải của mạng.

Kết nối Direct: một máy tính được kết nối trực tiếp đến Internet thông qua một giao diện mạng sẽ cho phép người dùng có được chức năng cao nhất. Mỗi một máy tính được kết nối theo cách này phải có một địa chỉ Internet cần thiết. Loại kết nối này cũng là loại đắt nhất.

Kết nối Serial: loại kết nối này có thể là SLIP (Serial Line Internet Protocol) hay PPP (Point to Point Protocol). Cả hai cách thức này đều cho ra các dịch vụ giống nhau trên một đường modem nối tiếp (serial). Từ khi kết nối này đưa ra chức năng TCP/IP và ICMP đầy đủ thì mỗi máy tính được cấu hình trong trường hợp này yêu cầu một địa chỉ Internet của chính nó. Loại kết nối này là theo yêu cầu dịch vụ, ở tốc độ thấp hơn, vì vậy giảm tải và có lỗ hổng Internet còn lại khi kết nối là “sống”.

Một điểm quan trọng của các thanh tra viên về bảo mật mạng cần nhớ là hầu hết các kết nối TCP dial-up, cả SLIP và PPP, đều ấn định một địa chỉ IP đến một thiết bị kết nối động. Điều này nghĩa là rằng, khi một hệ thống dial-up đến một ISP (Internet Service Provider), thì ISP sẽ gán cho nó một địa chỉ tại điểm đó. Nó cũng có nghĩa rằng, địa chỉ của người dial-up có thể thay đổi một lần hay nhiều lần khi hệ thống kết nối. Điều này có thể gây ra một số vấn đề nghiêm trọng cho các nhà bảo mật khi họ đang cố gắng lần theo sự truy cập đằng sau firewall và router ghi để ghi các địa chỉ IP cụ thể.

Kết nối truy cập Host: một loại hạn chế nhất của sự truy cập mạng là account người dùng trên một host được kết nối trực tiếp đến Internet. Sau đó người dùng sẽ sử dụng một thiết bị kết cuối để truy cập vào host đó bằng việc sử dụng một kết nối nối tiếp chuẩn. Loại kết nối này đơn giản trong truy cập.

Kết nối Sneaker-Net: đây là loại kết nối cực kỳ đơn giản, nó có từ khi các máy tính không có sự kết nối bằng điện. Tuy nhiên nó lại là loại an toàn nhất bởi vì các hacker sẽ không thể truy cập trực tiếp đến máy tính của các người dùng. Ở đây, nếu thông tin và các chương trình được yêu cầu trên máy tính thì chúng phải được biến đổi từ một máy tính được nối mạng đến máy tính người dùng thông qua môi trường từ tính hoặc bằng tay.

Tất cả các máy tính với các kết nối direct, SLIP, PPP phải có địa chỉ IP của riêng chúng và các thành viên làm về công tác bảo mật phải có kiến thức về các lỗ hổng liên quan đến các kết nối này. Với các kênh truyền thông, nó làm việc theo cả hai cách: việc có người dùng truy cập đến Internet từ đó Internet cũng có truy cập đến người dùng này. Vì vậy, các máy tính phải được bảo vệ và bảo đảm Internet cũng phải có một truy cập giới hạn.

Để kết nối đến các mạng con khác nhau cần phải có các thiết bị phần cứng cần thiết như: Repeater, Modem, Bridge, Router, Getway, Packet fillter, Firewall, Cyberwall… chúng tôi sẽ trình bày chi tiết cho các bạn về các phần cứng này ở bài sau, mời các bạn đón đọc.

Phạm Văn Linh

Các cấu hình CSDL Client/Server

October 17, 2007

Nhìn chung mọi ứng dụng cơ sở dữ liệu đều bao gồm các phần:

  • Thành phần xử lý ứng dụng (Application processing components)
  • Thành phần phần mềm cơ sở dữ liệu (Database software componets)
  • Bản thân cơ sở dữ liệu (The database itself)

Các mô hình về xử lý cơ sở dữ liệu khác nhau là bởi các trường hợp của 3 loại thành phần nói trên định vị ở đâu. Bài viết này này xin giới thiệu 5 mô hình kiến trúc dựa trên cấu hình phân tán về truy nhập dữ liệu của hệ thống máy tính Client/Server.

– Mô hình cơ sở dữ liệu tập trung (Centralized database model)
– Mô hình cơ sở dữ liệu theo kiểu file – server (File – server database model)
– Mô hình xử lý từng phần cơ sở dữ liệu (Database extract processing model)
– Mô hình cơ sở dữ liệu Client/Server (Client/Server database model)
– Mô hình cơ sở dữ liệu phân tán (Distributed database model)

1. Mô hình cơ sở dữ liệu tập trung (Centralized database model)

Trong mô hình này, các thành phần xử lý ứng dụng, phần mềm cơ sở dữ liệu và bản thân cơ sở dữ liệu đều ở trên một bộ xử lý.

Ví dụ người dùng máy tính cá nhân có thể chạy các chương trình ứng dụng có sử dụng phần mềm cơ sở dữ liệu Oracle để truy nhập tới cơ sở dữ liệu nằm trên đĩa cứng của máy tính cá nhân đó. Từ khi các thành phần ứng dụng, phần mềm cơ sở dữ liệu và bản thân cơ sở dữ liệu cùng nằm trên một máy tính thì ứng dụng đã thích hợp với mô hình tập trung.

Hầu hết công việc xử lý luồng thông tin chính được thực hiện bởi nhiều tổ chức mà vẫn phù hợp với mô hình tập trung. Ví dụ một bộ xử lý mainframe chạy phần mềm cơ sở dữ liệu IMS hoặc DB2 của IBM có thể cung cấp cho các trạm làm việc ở các vị trí phân tán sự truy nhập nhanh chóng tới cơ sở dữ liệu trung tâm. Tuy nhiên trong rất nhiều hệ thống như vậy, cả 3 thành phần của ứng dụng cơ sở dữ liệu đều thực hiện trên cùng một máy mainframe do vậy cấu hình này cũng thích hợp với mô hình tập trung.

2. Mô hình cơ sở dữ liệu theo kiểu file – server (File – server database model)

Trong mô hình cơ sở dữ liệu theo kiểu file – server các thành phần ứng dụng và phần mềm cơ sở dữ liệu ở trên một hệ thống máy tính và các file vật lý tạo nên cơ sở dữ liệu nằm trên hệ thống máy tính khác. Một cấu hình như vậy thường được dùng trong môi trường cục bộ, trong đó một hoặc nhiều hệ thống máy tính đóng vai trò của server, lưu trữ các file dữ liệu cho hệ thống máy tính khác thâm nhập tới. Trong môi trường file – server, phần mềm mạng được thi hành và làm cho các phần mềm ứng dụng cũng như phần mềm cơ sở dữ liệu chạy trên hệ thống của người dùng cuối coi các file hoặc cơ sở dữ liệu trên file server thực sự như là trên máy tính của người chính họ.

Mô hình file server rất giống với mô hình tập trung. Các file cơ sở dữ liệu nằm trên máy khác với các thành phần ứng dụng và phần mềm cơ sở dữ liệu; tuy nhiên các thành phần ứng dụng và phần mềm cơ sở dữ liệu có thể có cùng thiết kế để vận hành một môi trường tập trung. Thực chất phần mềm mạng đã làm cho phần mềm ứng dụng và phần mềm cơ sở dữ liệu tưởng rằng chúng đang truy nhập cơ sở dữ liệu trong môi trường cục bộ. Một môi trường như vậy có thể phức tạp hơn mô hình tập trung bởi vì phần mềm mạng có thể phải thực hiện cơ chế đồng thời cho phép nhiều người dùng cuối có thể truy nhập vào cùng cơ sở dữ liệu.

3. Mô hình xử lý từng phần cơ sở dữ liệu (Database extract processing model)

Một mô hình khác trong đó một cơ sở dữ liệu ở xa có thể được truy nhập bởi phần mềm cơ sở dữ liệu, được gọi là xử lý dữ liệu từng phần

Với mô hình này, người sử dụng có thể tại một máy tính cá nhân kết nối với hệ thống máy tính ở xa nơi có dữ liệu mong muốn. Người sử dụng sau đó có thể tác động trực tiếp đến phần mềm chạy trên máy ở xa và tạo yêu cầu để lấy dữ liệu từ cơ sở dữ liệu đó. Người sử dụng cũng có thể chuyển dữ liệu từ máy tính ở xa về chính máy tính của mình và vào đĩa cứng và có thể thực hiện việc sao chép bằng phần mềm cơ sở dữ liệu trên máy cá nhân.

Với cách tiếp cận này, người sử dụng phải biết chắc chắn là dữ liệu nằm ở đâu và làm như thế nào để truy nhập và lấy dữ liệu từ một máy tính ở xa. Phần mềm ứng dụng đi kèm cần phải có trên cả hai hệ thống máy tính để kiểm soát sự truy nhập dữ liệu và chuyển dữ liệu giữa hai hệ thống. Tuy nhiên, phần mềm cơ sở dữ liệu chạy trên hai máy không cần biết rằng việc xử lý cơ sở dữ liệu từ xa đang diễn ra vì người sử dụng tác động tới chúng một cách độc lập.

4. Mô hình cơ sở dữ liệu Client/Server (Client/Server database model)

Trong mô hình cơ sở dữ liệu Client/Server, cơ sở dữ liệu nằm trên một máy khác với các máy có thành phần xử lý ứng dụng. Nhưng phần mềm cơ sở dữ liệu được tách ra giữa hệ thống Client chạy các chương trình ứng dụng và hệ thống Server lưu trữ cơ sở dữ liệu.

Trong mô hình này, các thành phần xử lý ứng dụng trên hệ thống Client đưa ra yêu cầu cho phần mềm cơ sở dữ liệu trên máy client, phần mềm này sẽ kết nối với phần mềm cơ sở dữ liệu chạy trên Server. Phần mềm cơ sở dữ liệu trên Server sẽ truy nhập vào cơ sở dữ liệu và gửi trả kết quả cho máy Client.

Mới nhìn, mô hình cơ sở dữ liệu Client/Server có vẻ giống như mô hình file – server, tuy nhiên mô hình Client/Server có rất nhiều thuận lợi hơn mô hình file – server. Với mô hình file – server, thông tin gắn với sự truy nhập cơ sở dữ liệu vật lý phải chạy trên toàn mạng. Một giao tác yêu cầu nhiều sự truy nhập dữ liệu có thể gây ra tắc nghẽn lưu lượng truyền trên mạng.

Giả sử một người dùng cuối tạo ra một vấn tin để lấy dữ liệu tổng số, yêu cầu đòi hỏi lấy dữ liệu từ 1000 bản ghi, với cách tiếp cận file – server nội dung của tất cả 1000 bản ghi phải đưa lên mạng, vì phần mềm cơ sở dữ liệu chạy trên máy của người sử dụng phải truy nhập từng bản ghi để thoả mãn yêu cầu của người sử dụng. Với cách tiếp cận cơ sở dữ liệu Client/Server, chỉ có lời vấn tin khởi động ban đầu và kết quả cuối cùng cần đưa lên mạng, phần mềm cơ sở dữ liệu chạy trên máy lưu giữ cơ sở dữ liệu sẽ truy nhập các bản ghi cần thiết, xử lý chúng và gọi các thủ tục cần thiết để đưa ra kết quả cuối cùng.

Front-end software

Trong mô hình cơ sở dữ liệu Client/Server, thường nói đến các phần mềm front-end software và back-end software. Front-end software được chạy trên một máy tính cá nhân hoặc một workstation và đáp ứng các yêu cầu đơn lẻ riêng biệt, phần mềm này đóng vai trò của Client trong ứng dụng cơ sở dữ liệu Client/Server và thực hiện các chức năng hướng tới nhu cầu của người dùng cuối cùng, phần mềm Front-end software thường được chia thành các loại sau:

– End user database software: Phần mềm cơ sở dữ liệu này có thể được thực hiện bởi người sử dụng cuối trên chính hệ thống của họ để truy nhập các cơ sở dữ liệu cục bộ nhỏ cũng như kết nối với các cơ sở dữ liệu lớn hơn trên cơ sở dữ liệu Server.
– Simple query and reporting software: Phần mềm này được thiết kế để cung cấp các công cụ dễ dùng hơn trong việc lấy dữ liệu từ cơ sở dữ liệu và tạo các báo cáo đơn giản từ dữ liệu đã có.
– Data analysis software: Phần mềm này cung cấp các hàm về tìm kiếm, khôi phục, chúng có thể cung cấp các phân tích phức tạp cho người dùng.
– Application development tools: Các công cụ này cung cấp các khả năng về ngôn ngữ mà các nhân viên hệ thống thông tin chuyên nghiệp sử dụng để xây dựng các ứng dụng cơ sở dữ liệu của họ. Các công cụ ở đây bao gồm các công cụ về thông dịch, biên dịch đơn đến các công cụ CASE (Computer Aided Software Engineering), chúng tự động tất cả các bước trong quá trình phát triển ứng dụng và sinh ra chương trình cho các ứng dụng cơ sở dữ liệu.
– Database administration Tools: Các công cụ này cho phép người quản trị cơ sở dữ liệu sử dụng máy tính cá nhân hoặc trạm làm việc để thực hiện việc quản trị cơ sở dữ liệu như định nghĩa các cơ sở dữ liệu, thực hiện lưu trữ hay phục hồi.

Back-end software

Phần mềm này bao gồm phần mềm cơ sở dữ liệu Client/Server và phần mềm mạng chạy trên máy đóng vai trò là Server cơ sở dữ liệu.

5. Distributed database model (Mô hình cơ sở dữ liệu phân tán)

Cả hai mô hình File – Server và Client/Server đều giả định là dữ liệu nằm trên một bộ xử lý và chương trình ứng dụng truy nhập dữ liệu nằm trên một bộ xử lý khác, còn mô hình cơ sở dữ liệu phân tán lại giả định bản thân cơ sở dữ liệu có ở trên nhiều máy khác nhau.

10 thủ thuật với modem

October 9, 2007

10 thủ thuật đối với Modem

1. Cập nhật driver mới nhất

    Tr­ớc hết và tốt nhất, bạn phải chắc rằng mình có các driver mới nhất cho modem của mình. Các driver này th­ờng có ở trang Web của nhà sản xuất. Nếu không biết chính xác địa chỉ trang Web của nhà sản xuất, bạn đọc kỹ tài liệu kèm theo modem để tìm tên chip dùng cho modem. Bạn có thể vào trang Web của nhà sản xuất bằng cách gõ tên của loại chip vào ô địa chỉ trong trình duyệt.

2. Phục hồi các thiết lập ban đầu

    Nếu modem của bạn không hoạt động, hãy thử dùng lệnh AT&F1 hoặc ATZ. Lệnh AT&F1 th­ờng phục hồi cấu hình khi xuất x­ởng modem, còn ATZ th­ờng đặt lại cấu hình mặc định (default).

3. Không có tín hiệu và âm thanh của modem

    Nếu bạn không thể nghe đ­ợc tín hiệu, hãy cắm lại jack nối với đ­ờng dây điện thoại và kiểm tra xem đã chỉnh âm l­ợng đủ lớn để có thể nghe đ­ợc âm thanh phát ra từ modem ch­a. Nếu modem nhận đ­ợc tín hiệu và gọi đi đ­ợc nh­ng không thể kết nối thì nguyên nhân phần nhiều là từ phía modem mà bạn đang kết nối tới.

    Để điều chỉnh âm l­ợng của modem, vào Control Panel/Modem, chọn Properties và điều chỉnh thanh tr­ợt. Nếu vẫn không thể kết nối đ­ợc, hãy thử quay một số khác để kiểm tra.

4. Dây nối ngắn

    Nếu có thể đ­ợc, hãy dùng dây nối càng ngắn càng tốt, vì dùng dây dài, tín hiệu nhận đ­ợc sẽ kém, cung có nghia là kết nối sẽ chậm hon.

5. Hãy để modem đ­ợc riêng biệt

    Không nên cắm điện thoại vào chấu cắm Phone trên modem, điều đó có thể làm ảnh h­ởng tới các kết nối Internet/Fax/BBS. Đối với một số modem, khi bạn cắm điện thoại vào, nó chỉ có thể kết nối đ­ợc ở tốc độ 31.200? Nh­ng khi bạn rút điện thoại ra nó lại đạt tốc độ 33.600?

6. Chỉnh thông số MTU cực đại

    Một số ng­ời nhận thấy rằng tác vụ truyền file trên Internet khá chậm, th­ờng chỉ trong khoảng 900 -1800 ký tự (character), ngay cả với modem 56K. Nguyên nhân có thể liên quan đến một thông số của Win95/98 gọi là Maximum Transmission Unit (MTU). Hãy nhìn vào mục “Bytes received/sec” trong System Monitor và so sánh thông số đó với thông số mà trình duyệt Web của bạn thông báo. Hai số này chỉ nên khác nhau trong khoảng 10%-12%. Nếu thông số do System Monitor thông báo là 3300 thì thông số còn lại phải vào khoảng 3000. Nếu nh­ 2 thông số này sai lệch quá nhiều thì có thể là do thông số MTU của Windows 95/98. Microsoft vẫn ch­a đ­a ra ch­ong trình nào để sửa thông số này, nh­ng bạn có thể tải về từ địa chỉ: http://www.aimnet.com/Aạjnavas/modem/tcpipcfg.exe.

7. Bộ đệm lớn hon

    Trong bất cứ tác vụ truyền dữ liệu nào cung sẽ có một phần dữ liệu bị mất đi trên đ­ờng truyền và không có cách nào để lấy lại đ­ợc. Nh­ng bạn có thể tăng tỷ lệ nhận tín hiệu chính xác bằng cách bổ sung thêm một dòng lệnh vào file SYSTEM.INI. Có điều tr­ớc khi bắt đầu, bạn cung nên biết cách Windows điều khiển luồng dữ liệu tới nh­ thế nào. Modem của bạn gửi dữ liệu tới trình điều khiển COMM của Windows, trình điều khiển này l­u dữ liệu vào một vùng đệm cho tới khi ch­ong trình truyền thông của bạn lấy lại. Nh­ng thật không may là công việc này chỉ đ­ợc làm khi ch­ong trình rảnh rỗi, kết quả là nó không thể lấy đ­ợc dữ liệu từ trình điều khiển COMM th­ờng xuyên nh­ yêu cầu.

    ở chế độ mặc định, Windows chỉ dành ra một phần bộ nhớ có khả năng l­u trữ 128 ký tự (character). Nh­ng một khi modem đã đ­ợc nối mạng thì dòng dữ liệu đi vào máy bạn một cách liên tục. Máy tính có thể tạm thời ngừng dòng dữ liệu đi vào này, nh­ng làm nh­ vậy sẽ mất thời gian nên dữ liệu vẫn tiếp tục đi vào mà không đ­ợc l­u giữ ở bộ đệm của trình điều khiển COMM. Nếu kết nối của bạn chậm hoặc ch­ong trình truyền thông nhanh thì bộ đệm chứa 128 ký tự có thể đủ, nh­ng nếu ng­ợc lại thì l­ợng bộ nhớ đệm đó sẽ là quá nhỏ.

    Bạn có thể khắc phục đ­ợc vấn đề này theo cách sau:

+ Mở file SYSTEM.INI bằng một trình soạn thảo văn bản.

+ Tìm mục [386enh]

+ Thêm dòng có dạng nh­ sau: COMxBuffer=num

    trong đó “x” là một số từ 1 tới 4 cho biết tên của cổng COM mà modem của bạn sử dụng, còn “num” là số trong khoảng 128 tới 10.000 để xác lập độ lớn của bộ đệm. Th­ờng bạn nên đặt ở giá trị 10.000. Sau đó nếu trong thời gian tải file về mà tốc độ truyền bị giảm dần thì hãy đặt một số nhỏ hon cho đến khi vừa ý.

    Bạn cần phải khởi động lại Windows để xác lập này có tác dụng.

8. Tiếp thêm sức mạnh cho các cổng COM

    Thông th­ờng, Windows 95/98 đặt cấu hình cho các cổng COM ở tốc độ 9.600bps, nh­ng nếu bạn sử dụng modem 14,4 Kbps thì nên tăng trị số này.

    Mở Control Panel/System, kích chuột vào tab Device Manager, mở rộng nhánh Ports, nhấn đúp chuột vào mỗi cổng COM, chọn thanh Port Setting và thay đổi thông số “Bits Per Second” lên ít nhất là 57.600 (hình 2), sau đó nhấn nút Advanced và đánh dấu chọn “Use FiFO buffers [requires 16550 compatible UART]”.

9. Truyền dữ liệu nhanh hon và tăng tốc kết nối

    Với Windows 95/98, mở Control Panel/Modem, chọn nút Properties; trong thanh General, chọn “Maximum Speed” là 115.200; trong thanh Connection, chọn Advanced và đánh dấu chọn “User Error Control”, “Compress Data” và “Use Flow Control (Hardware)”.

10. Giảm thiểu nhiễu đ­ờng dây điện thoại

    Nhiễu (tiếng ồn) đ­ờng dây điện thoại là một trong những yếu tố dễ phát hiện nhất. Nhiễu đ­ờng dây không phải là vấn đề với các modem thuộc loại ISDN, DSL hoặc modem cáp mà với loại đ­ờng dây điện thoại kiểu tuần tự (analog), nh­ ở n­ớc ta thì nó là một trong những nguyên nhân chính dẫn đến kết nối chậm.

    Để kiểm tra mức độ tiếng ồn, bạn nhấc ống nghe lên và lắng nghe âm thanh. Có thể bạn sẽ nghe thấy các âm thanh rè rè khác nhau và khác âm thanh tín hiệu, đó có thể là do chất l­ợng dây điện thoại kém, do hoi n­ớc hoặc một vài nhân tố khác. Cách tốt nhất để giảm bớt tiếng ồn đ­ờng dây là cố gắng sử dụng dây điện thoại càng ngắn càng tốt, nếu vẫn không đ­ợc hãy gọi nhân viên sửa chữa điện thoại của B­u điện đến để kiểm tra chất l­ợng đ­ờng dây.

Hành trình cơ bản của một gói dữ liệu trên mạng

October 9, 2007

Mục đích của bài viết này là mang lại một cái nhìn cơ bản về hành trình của các gói dữ liệu trao đổi trên Internet từ việc tạo các gói được tạo đến các Switch, Router, NAT và cách thức truyền tải dữ liệu trên Internet. Chủ đề này sẽ rất hay đối với những người mới nghiên cứu về lĩnh vực mạng và bảo mật và những người có ít kiến thức cơ bản về quá trình xử lý dữ liệu trên Internet.

Giới thiệu

Có lẽ trong một vài bài báo, chúng ta cũng đã thấy được sự quan trọng của hai lĩnh vực về bảo mật máy tính đối với người mới sử dụng đó là: programming và networking. Trong khi chúng là hai phần khác nhau thì cả hai cần phải được xem có tầm quan trọng như nhau. Nếu không có việc lập trình các giao thức mạng thì sẽ không có mạng. Điều cần hỏi ở đây là: có bắt buộc cần phải có một lập trình viên để nắm được một cách đầy đủ các khái niệm về mạng và lý thuyết mạng ở mức thấp hay không? Trong nhiều trường hợp là không cần như vậy. Mặc dù vậy, một sự ham hiểu của các độc giả sẽ là tốt và có thể hướng anh ta vào việc lập trình tại một vài điểm để có thêm các thử nghiệm với các giao thức khác và lý thuyết mạng.

Với những người mới với lĩnh vực này, ấn tượng đầu tiên với một máy tính là cái gì đó khó có thể quên. Khi một ai đó khám phá ra Internet, sự giàu có của thông tin tạo cho họ một cảm giác kinh sợ và tạo nên cho họ một hứng khởi là các kỹ thuật bên trong của nó làm việc như thế nào. Bất kỳ ai dường như cũng bị rơi vào một thế giới hoàn toàn mới khi sử dụng một máy tính để kết nối với các hệ thống khác bên phía bờ kia của thế giới. Họ sẽ tò mò về các máy tính và mạng làm các công việc này như thế nào? Và thông tin truyền từ máy tính này đến máy tính kia đi qua tất cả các thiết bị khác nhau để đến được đích của nó như thế nào?

Các hành trình

Khi một ứng dụng Internet được gọi thì một loạt các sự kiện sẽ xảy ra. Trong bài viết này chúng tôi chỉ giới thiệu một cách đơn giản một gói được tạo ra như thế nào và các thiết bị sẽ đưa nó đi theo nhiều con đường để đến đích của nó ra sao. Việc hiểu biết về việc gì xảy ra giữa điểm A và điểm Z có thể khá hữu ích trong việc tiếp cận đến lĩnh vực này.

Bây giờ chúng ta nên mô tả những gì xảy ra từ thời điểm một ứng dụng được gọi đến lúc các gói được tạo ra bằng các ứng dụng tới được đích của nó. Giả sử rằng bạn sử dụng Firefox để kiểm tra xem một tin tức trên trang web yêu thích của bạn. Một loạt các sự kiện đã được thiết lập nên trong sự chuyển động này là hoàn toàn trong suốt đối với bạn. Sau khi bắt tay TCP/IP ban đầu, trình duyệt web của bạn sẽ gửi một yêu cầu đến máy chủ web server mà trang chủ của bạn đang hỏi cho trang chủ của nó. Thông tin yêu cầu HTTP GET bây giờ cần phải gửi đến web server. Những gì xảy ra với Firefox khi kích ứng dụng của bạn là làm một yêu cầu đến hệ thống. Quá trình này sẽ đưa dữ liệu mà Firefox muốn gửi được copy từ các không gian nhớ của các ứng dụng đến bộ đệm bên trong không gian trung tâm.

Phụ thuộc vào giao thức truyền tải nào mà ứng dụng sử dụng, lớp socket sẽ gọi cả UDP và TCP. Chúng ta cần phải nhớ rằng có rất nhiều ứng dụng không sử dụng TCP như một giao thức truyền tải. DNS sử dụng cả hai UDP và TCP, trong khi các ứng dụng khác như là TFTP chỉ sử dụng UDP. Lớp socket gọi giao thức truyền tải thích hợp, khi đó dữ liệu sẽ được copy xuống vào bộ đệm socket.

Sự chia nhỏ dữ liệu

Khi copy dữ liệu từ yêu cầu GET được thực hiện đến một bộ đệm socket, TCP sẽ chia nhỏ dữ liệu này nếu cần thiết. Mặc dù một yêu cầu GET là tương ứng với một gói và sẽ đi bên trong MTU của Ethernet không có vấn đề gì, nhưng việc gì sẽ xảy ra nếu các yêu cầu của trình duyệt vượt quá MTU? Khi đó TCP sẽ chia nhỏ dữ liệu để bảo đảm kích thước phù hợp với giới hạn 1500bytes của Ethernet MTU. Một điểm chính đáng nhớ ở đây là sự chia nhỏ này sẽ xảy ra tại lớp TCP nếu ứng dụng yêu cầu sử dụng TCP như là giao thức truyền tải dữ liệu của chúng.

Việc truyền tải dữ liệu trong môi trường mạng.

Dữ liệu được tạo hợp với chức năng lớp truyền tải riêng của nó, hãy xem xét lớp IP. Tại đây, header IP được xây dựng và tất cả các địa chỉ IP quan trọng được gán vào. Sau đó, dự liệu sẽ theo các đường liên kết dữ liệu, nơi mà cả hai lớp điều khiển liên kết logic và điều khiển truy cập thực hiện phần việc này. Cuối cùng, dữ liệu được sẵn sàng để truyền bằng các lớp vật lý được tích hợp trong hệ thống bằng các NIC card. Với hầu hết các người dùng tại nhà, một router SoHo đã được kết hợp của cả chuyển mạch (switch) và router đơn giản. Với người dùng trong công ty, switch là một phần cứng tách biệt với router của nó. Nếu trong môi trường công ty các máy tính có thể nối với các switch qua đường cáp. Nếu switch không có bảng hard-coded CAM thì swtich cần chú ý đến địa chỉ MAC của máy tính (duy nhất cho mỗi Ethernet card). Khi gói dữ liệu đến từ quá trình truyền tải của nó mang theo dữ liệu của website như được yêu cầu trong GET request chuyển mạch theo hướng ngược của trình khách nó sẽ hiểu nơi để gửi các gói đó trở lại.

Trình khách hiểu các gateway mặc định của nó như thế nào? Dù nó là mạng công ty hay tại nhà thì hệ thống sẽ luôn thực hiện một gói DHCP một lần để nó khởi động và lấy thông tin chính từ server DHCP. Do không phải tất cả các hệ thống đều sử dụng DHCP, vì thế không có địa chỉ IP hay gateway được định trước. Thông tin trong đó như là tên server DNS nào được sử dụng, địa chỉ IP của nó và địa chỉ IP gateway mặc định. Nếu DHCP bị tắt, người quản trị hệ thống sẽ phải vào tất cả các thông tin này bằng tay. Cực kỳ không hiệu quả chút nào, nên nó giải thích tại sao DHCP được bật trong hầu hết các mạng.

Với gateway mặc định ở gần, máy tính hiểu đích đi đến để truy cập Internet và lấy dữ liệu trang web khi được yêu cầu bởi Firefox. Sau khi các gói đi qua switch nó hình thành đường để dễ dàng đi qua firewall đến router. Các packet nên được cho qua một firewall, khi đó firewall sẽ làm một vài công việc chính. Một firewall với đầy đủ tính năng sẽ ghi địa chỉ IP và port nguồn, cộng địa chỉ IP và port đích. Firewall sẽ giữ thông tin này trong bảng trạng thái của bộ nhớ, bằng cách này nó sẽ quy định sự truy cập vào mạng bên trong như thế nào. Nếu một gói không được ghi thì nó sẽ không được truy cập vào trong mạng. Trong một dịp khác chúng tôi sẽ giới thiệu với các bạn về vai trò của firewall đối với việc bảo vệ máy tính của bạn như thế nào.

Các router và NAT

Bây giờ, khi các gói đã đi qua firewall, nếu hiện tại nó đang đi đến router. Địa chỉ IP cá nhân mà các gói có (giả định nó là một địa chỉ cơ bản 192.168/16) sẽ được biến đổi thành một địa chỉ IP chung có thể định tuyến, cái mà được cho bởi ISP của bạn. Nó cũng được gán cho router của bạn. Các gói bây giờ bắt đầu cuộc hành trình của nó trên Internet và qua vô số các router trong chuyến đi của nó. Mỗi thời điểm đó, các gói hướng đến một router khác. Vậy cái gì xảy ra với chính các gói.

Hãy bắt đầu bằng việc nhìn vào router. Nó sẽ định tuyến các gói dựa vào thông tin trong bảng định tuyến của chính nó. Đến khi router tiếp theo nhận được các gói này nó sẽ tính toán theo bảng định tuyến của nó để tìm ra con đường ngắn nhất cho việc truyền tải gói tin này. Một trong vài phần nó sẽ thay đổi đó là TTL “time to live”. Bây giờ phần header IP của nó được thay đổi, do đó các router cần phải tính toán một giá trị tổng mới cho các gói. Cứ tương tự như vậy cho tới khi các gói đến được địa chỉ đích mong muốn của nó.

Lớp vật lý sẽ thực hiện một IRQ đến CPU đã chỉ rõ rằng có dữ liệu đã được xử lý. Sau đó, dữ liệu sẽ đi lên lớp data link, đây chính là nơi mà webserver sẽ nhận ra MAC và tiếp tục đi lên lớp IP, sau đó là lớp transport (nơi dữ liệu được đưa vào bộ đệm). Tại lớp này các thông tin của ứng dụng mà dữ liệu mang theo cho nó được xử lý ở đây. Kết quả cuối cùng là thông tin được yêu cầu cho yêu cầu GET đã được gửi trở lại. Tương tự như thế với một gói mới thì quá trình cũng xảy một loạt các sự kiện như vậy.

Kết luận

Nhìn chung bài báo này đã cố gắng để trình bày cho các bạn có một kiến thức cơ bản về mạng và các khái niệm chung của routing, switching và NAT. Mong các bạn có thể tiếp tục thực hiện những nghiên cứu thêm để nắm sâu hơn về nó và chúc các bạn thành công.

Mạng máy tính

October 9, 2007

Giới thiệu chung về mạng máy tính

I. Giới thiệu chung

    Mạng máy tính là một số các máy tính được nối kết với nhau theo một cách nào đó nhằm mục đích để trao đổi chia sẽ thông tin cho nhau với những ưu điểm:


Nhiều người có thể dùng chung một một thiết bị ngoại vi (máy in, modem..), một phần mềm.
Dữ liệu được quản lư tập trung nên an toàn hơn, sự trao đổi thông tin dữ liệu giữa những người dùng sẽ nhanh chóng hơn, thuận lợi hơn.
Người dùng có thể trao đổi thư tín với nhau một cách dễ dàng và nhanh chóng. Có thể cài đặt Internet trên một máy bất kỳ trong mạng, sau đó thiết lập, định cầu h́nh cho các máy khác có thể thông qua máy đă được cài đặt chương tŕnh share Internet để cũng có thể kết nối ra Internet.

II. Phân loại mạng máy tính

Mạng máy tính có thể được phân bố trong các phạm vi khác nhau, người ta có thể phân ra các loại mạng như sau:

LAN (local Area Network) là mạng cục bộ, kết nối các máy tính trong một khu vực bán kính hẹp, thường th́ khoảng vài trăm mét. Môi trường truyền thông có tốc độ kết nối cao, như cáp xoắn, cáp đồng trục, cáp quang. Mạng LAN thường được sử dụng trong nội bộ của một cơ quan, một tổ chức. Các LAN kết nối lại với nhau thành mạng WAN.

WAN (Wide Area Network) là mạng diện rộng, kết nối máy tính trong nội bộ quốc gia, hay giữa các quốc gia trong cùng một châu lục. Thông thường kết nối này được thực hiện thông qua mạng viễn thông. Các Wan kết nối với nhau thành GAN.

GAN (Global Area Network) kết nối máy tính từ các châu lục khác nhau. Thông thường kết nối này được thực hiện thông qua mạng viễn thông và vệ tinh.

MAN (Metropolitan Area Network) Kết nối các máy tính trong phạm vi một thành phố. Kết nối được thực hiện thông qua môi trường truyền thông tốc độ cao (50/100 M bis/s).

III. Bạn nên có mạng nào

    Tùy theo tổng số máy tính, tổng số thiết bị mà bạn sẽ dùng. Khoảng cách tối đa giữa các thiết bị. ở đây chúng tôi chỉ bàn về mạng cục bộ LAN dạng h́nh sao (Start topology). Đây là kểu mạng được sử dụng nhiều nhất hiện nay.

Mạng cục bộ (LAN) là một mạng với hệ truyền thông tốc độ cao, được thiết kế để nối kết các máy tính lại với nhau trong một khu vực địa lư nhỏ như một toà nhà, một trường học?.cho phép người sử dụng có thể dùng chung những tài nguyên như máy in, ổ đĩa CD-ROM, các phần mềm ứng dụng như chỉ cần một máy trong mạng cài chương tŕnh Share Internet, th́ các máy khác vẫn có thể kết nối ra Internet được. điều này sẽ đáp ứng được nhu cầu là khi trong văn pḥng của bạn một khi các máy tính đă được nối kết thành mạng LAN và mỗi người sử dụng máy đều muốn truy cập Internet và những dịch vụ khác về Internet…., trong khi đó bạn chỉ có một modem và một tài khoản truy cập Internet. Giải pháp lắp đặt cho mỗi máy một modem, kéo cho mỗi máy 1 line điện thoại th́ quá tốn kém, hoặc nếu ai muốn truy cập Internet th́ lắp modem vào máy ḿnh và nối dây điện thoại tới đó th́ rất bất tiện nếu đó là loại modem gắn trong, hoặc đường line điện thoại quá ngắn ..v.v .. . Để giải quyết vấn đề trên, các phần mềm giả lập Proxy Server được h́nh thành. Các phần mềm hiệu quả trong việc chia sẻ internet là Wingate, WinRoute, WinProxy, ISA Server…

IV. Giới thiệu chung về mạng LAN dạng h́nh sao (Star topology)

    Mạng h́nh sao bao gồm một điểm trung tâm và các nút thông tin kết nối vào điểm trung tâm đó. Các nút thông tin là các thiết bị đầu cuối như máy tính, hay các thiết bị khác của mạng. Tại điểm trung tâm của mạng là nơi điều phối chính mọi hoạt động trong mạng với các chức năng:

Chuyển tiếp dữ liệu giữa các nút (các máy tính với nhau).

Nhận biết t́nh trạng của mạng, các nút ( các máy tính) đang nối kết mạng.

Theo dơi và xử lư trong quá tŕnh trao đổi thông tin.

Ưu và nhược điểm cuả mạng h́nh sao

Ưu điểm mạng h́nh sao:

Hoạt động theo nguyên lư kết nối song song nên nếu có một thiết bị nào đó ở một nút bất kỳ bị hỏng th́ mạng vẫn hoạt động b́nh thường, các máy c̣n lại vẫn hoạt động b́nh thường.

Là một kiểu mạng có cấu trúc đơn giản, và tính ổn định cao dể lắp đặt.

Mạng có thể mở rộng hoặc thu hẹp tùy theo yêu cầu của người sử dụng

    Nhược điểm mạng h́nh sao:

Sự mở rộng mạng phải phụ thuộc vào khả năng của thiết bị trung tâm.

Nếu thiết bị trung tâm lỗi th́ toàn bộ mạng sẽ bị tê liệt.

Khoảng cách tối đa từ các nút tới trung tâm bị hạn chế ( nhỏ hơn 100m).

Các thiết bị cần thiết trong mạng h́nh sao:

Thiết bị trung tâm: có thể dùng HUB hay Switch.

Cáp kết nối: Cáp xoắn.

Card giao tiếp mạng NIC (Network Interface Card) cho từng nút.

Hiện nay có rất nhiều loại card mạng khác nhau bạn có thể lựa chọn tùy theo tài chính của bạn.

V. Mô h́nh tổng quát của một mạng LAN dạng h́nh sao (Star topology)

3 từ không thể thiếu với website

October 2, 2007

Có ba từ đại diện cho những nhân tố then chốt trong thành công của bất cứ website nào. Nắm vững được tầm quan trọng của 3 từ này tức là bạn đã đạt được một nửa con đường tới thành công trên Internet. Và ngược lại, nếu không để ý đến chúng thì nhà kinh doanh sẽ khó lòng đạt được bất cứ một thành công tài chính nào từ chiến dịch marketing trên mạng.  

1. Miễn phí

Nhân tố then chốt trong toàn bộ thế giới Internet chỉ là một từ đơn giản “Miễn phí”. Đây là từ bạn phải biết nếu muốn kinh doanh thành công trên Internet. Cách dễ nhất để thu hút mọi người đến thăm website là cung cấp một vài dịch vụ miễn phí nào đó. Có thể là tin tức, số liệu, thông báo miễn phí hoặc một chương trình tìm kiếm miễn phí.

Mặc dù các chuyên gia công nghệ thông tin đưa ra rất nhiều lời khuyên khác nhau về cách thu hút người truy cập web, nhưng thực sự bí mật thu hút truy cập chỉ nằm trong một từ… miễn phí. Bạn nên đưa ra một số tiện ích hấp dẫn có liên quan đến thị trường mục tiêu của mình và cung cấp miễn phí trên website. Đây chính là “lưỡi câu” bí mật đầy hiệu quả mà bạn đặt trên website liên tục 24h mỗi ngày và 7 ngày trong tuần.

Sau đây là một số “lưỡi câu” đã được sử dụng rất thành công để thu hút lượng truy cập và lôi kéo khách hàng quay trở lại trên website: Thông báo, Sách điện tử, Trang tập hợp mọi đường link theo chủ đề, Rao vặt, Real Audio hay Real Video, Newsletter, Nhóm thảo luận, Bưu thiếp và Các chương trình tìm kiếm, tất nhiên tất cả đều miễn phí. Tiện ích miễn phí tốt nhất mà bạn nên cung cấp cho hầu hết các thị trường là một bản thông tin miễn phí hướng về sản phẩm của bạn. Chẳng hạn, đưa ra bài viết miễn phí về 11 bí quyết thu hút truy cập, nếu bạn bán một báo cáo nghiên cứu về Thu hút truy cập trên Internet. Hay đưa ra hướng dẫn cách ngăn chó không gặm đồ đạc trong nhà nếu bạn chào bán các khóa huấn luyện thú nuôi.

Nếu bạn tạo một bản tin miễn phí có liên hệ đến sản phẩm chính của mình, bạn có thể sử dụng các hệ thống tiếp nối tự động và tạo một hệ thống tiếp nối tự động gửi các bức thư chào hàng đến những người đã đăng ký nhận tin miễn phí. Bạn nên đặt bản tin miễn phí trong một hệ thống phản hồi nhiều chiều, sau khi nhận được thông tin đầu tiên của hệ thống phản hồi tự động. Sau đó, bạn cần lập trình để hệ thống tự gửi đi các bức thư chào hàng vào sau ngày một khách hàng đăng ký nhận bản tin miễn phí. Các bức thư này sẽ được lập trình để thực hiện đầy đủ một quá trình bán hàng.

Bản tin miễn phí với thư trả lời tự động là một khởi đầu tốt cho quá trình tìm kiếm khách hàng tiềm năng. Các bức thư bán hàng tiếp nối sẽ là nhân tố quan trọng để thực hiện bán hàng tự động trên website.

2. Sản phẩm mũi nhọn

Chìa khóa cho thành công của bất kỳ trang web thương mại nào là phải có một sản phẩm chính được coi là sản phẩm chủ đạo. Bạn không cần nhấn mạnh về tất cả các sản phẩm đối với mỗi khách hàng mới. Có quá nhiều sự lựa chọn sẽ làm khách hàng lúng túng. Hãy giới thiệu với họ một lựa chọn chính mà bạn luôn nhấn mạnh trên tòan bộ website. Một chuyên gia thương mại điện tử đã thử nghiệm cả hai phương pháp là tập trung vào một sản phẩm chính và giới thiệu một loạt sản phẩm như một catalog. Kết quả là cách tiếp cận 1 sản phẩm bán chạy gấp đôi cách tiếp cận kiểu catalog. Quá nhiều sản phẩm sẽ gây nhiễu cho các khách hàng, và còn dẫn đến tình trạng họ không thể quyết định chọn sản phẩm nào nên cuối cùng không mua gì cả. Mặc dù một số ít công ty lớn có thể thành công bằng cách tiếp cận kiểu catalog, nhưng đối với các công ty vừa và nhỏ nói chung thì cách làm này khá khó khăn.

Bạn nên sử dụng các sản phẩm khác như là phần phụ trợ để đa dạng hóa nguồn doanh thu.

3. Phụ trợ

Tuy nhiên, phần doanh thu từ sản phẩm phụ trợ không phải là nhỏ. Hiện nay, nguyên tắc của doanh số phụ trợ thường bị đa số công ty bỏ qua bởi nhiều người còn chưa nhận ra sức mạnh thực sự của lĩnh vực này.

Nếu bạn phát triển một sản phẩm phụ trợ tốt khiến nhiều khách hàng phải quay lại tìm mua trên website thì có thể coi là bạn đã có một cỗ máy kiếm tiền đều đặn.

Ví dụ: Hãy coi như bạn đang bán một đài radio loại rẻ và bộ đầu đĩa đắt tiền hơn. Đài radio có giá 50 USD (và phải trả 25 USD cho người cung cấp) và bộ đầu đĩa là 300 USD (trả cho người cung cấp 150 USD). Nếu sản phẩm thứ nhất bán cho khách hàng là 50 USD, bạn có 25 USD lợi nhuận, chưa tính đến khoản chi phí quảng cáo và bán hàng. Nếu coi chi phí quảng cáo và chăm sóc cho mỗi khách hàng bình quân là 20 USD, bạn sẽ chỉ kiếm được 5 USD lợi nhuận từ mỗi khách hàng mới. Điều gì xảy ra nếu bạn gửi kèm một lá thư chào hàng về sản phẩm 300 USD trong mỗi gói sản phẩm 50 USD được mua? Giả sử cứ 5 khách hàng mua đài radio có 1 người mua đầu video giá 300 USD, bạn đã có một khoản thu thêm là 150 USD trên 5 khách hàng. Lợi nhuận sản phẩm đầu vào là khoảng 25 USD cho 5 khách hàng trong khi lợi nhuận phụ trợ là 150USD, mà chỉ bạn chỉ tốn một vài cent cho các bức thư chào hàng gửi kèm trong sản phẩm.

10 điều cần biết khi chọn mua card đồ họa

August 23, 2007

Thật khó khăn khi bạn phải chọn lựa một card màn hình phù hợp với nhu cầu và túi tiền của bản thân. Trừ phi bạn là một người thường xuyên theo dõi thông tin về các bộ xử lý đồ họa (Graphics processing unit – GPU) và những bài phân tích, đánh giá chuyên sâu, nếu không bạn sẽ như lạc vào một ma trận.

Thật khó khăn khi bạn phải chọn lựa một card màn hình phù hợp với nhu cầu và túi tiền của bản thân. Trừ phi bạn là một người thường xuyên theo dõi thông tin về các bộ xử lý đồ họa (Graphics processing unit – GPU) và những bài phân tích, đánh giá chuyên sâu, nếu không bạn sẽ như lạc vào một ma trận.

Giống như CPU, GPU cũng luôn được cải tiến liên tục, do đó có một số luợng đáng kinh ngạc các card đồ họa mà bạn có thể chọn lựa. Tuy nhiên, một trong những “mánh” ưa thích của các nhà bán lẻ lại là đặt những card lỗi thời ngay bên cạnh những card mới nhất và mạnh nhất.

Sau đây là 10 điều bạn cần biết trước khi mua về cho mình một card đồ họa mới.

1. Bộ nhớ không phải là tất cả

Có thể nói, Ram là một phần quan trọng của card đồ họa bởi nếu bạn muốn chơi game ở độ phân giải cao và chất lượng hình ảnh tốt thì cần phải có nhiều dung lượng bộ nhớ. Đó là lý do tại sao các card đồ họa đời mới thường chứa nhiều Ram.

Nắm bắt được điều này, các nhà sản xuất card màn hình hiểu rằng những người không có kinh nghiệm sẽ lấy Ram làm tiêu chí đầu tiên để so sánh hai card đồ họa. Do đó họ thường sản xuất những card đồ họa sử dụng các GPU cấp thấp nhưng lại có tới 256 thậm chí 512 Mb Ram.

Điều này giống như việc bạn dùng xe đạp chạy trên đường cao tốc vậy, rộng rãi nhưng dù làm cách nào bạn cũng không đi nhanh hơn ôtô được. Những card kém sức mạnh sẽ có nhiều các thanh ghi trống hơn, tuy nhiên chất lượng hình ảnh tồi sẽ thấy rõ khi bạn bước vào trò chơi.

2. Tất cả là ở GPU

Bộ nhớ rất quan trọng nhưng trái tim thực sự của một card màn hình chính là GPU. Khi bạn quan sát trên một card đồ họa, hãy quan tâm đến loại GPU mà card sử dụng vì nó là nhân của các tác vụ xử lý 3D. Hiện nay những card đồ họa tốt nhất thường là của Nvidia và ATI.

Nhưng nếu chỉ chọn những card đồ họa có dòng chữ “Nvidia GeForce” hoặc “ATI Radeon” thì sẽ không đảm bảo cho bạn chọn được một card tốt. Hiện tại Nvidia và ATI đều đặt tên cho tất cả các card đồ họa của mình, từ card loại yếu cho tới những con quái vật “tân thời” với cùng cái tên Geforce hay ATI Radeon.

Đương nhiên số hiệu của card càng cao thì card có chất lượng cao tương ứng nhưng bạn cũng nên chú ý đến phần đuôi của card như GT, GS, GTX, XT và XTX. Chúng sẽ quyết định khả năng đổ bóng hay xung nhịp đồng hồ của card.

3. Pipeline, đổ bóng và xung nhịp đồng hồ

Trước đây, bạn có thể nhìn vào xung nhịp và số pipeline (hiểu nôm na là ống dẫn lệnh đồ họa, càng nhiều pipeline hình ảnh sẽ càng mượt mà) và điểm ảnh của một card đồ họa để đánh giá sức mạnh của nó. Nhưng nay, ánh sáng và các hiệu ứng khác có thể tạo ra thông qua phần mềm đổ bóng để có thể có được kết quả tương đương với sử dụng các pipeline.

Các GPU hiện tại đều có các bộ phận chuyên xử lý các vectơ phức tạp và các chương trình có thực hiện đổ bóng điểm. Trong tương lai, các bộ xử lý đổ bóng sẽ trở thành một bộ phận quan trọng trong các GPU đời mới. Gần đây nhất ATI cũng đã công bố số lượng các bộ xử lý đổ bóng trên mỗi pixel pipeline trong card Radeon X1900 XTX.

Vào thời điểm hiện nay, bạn vẫn có thể đánh giá card đồ họa thông qua số pixel pipeline mà nó có. Các nhà sản xuất GPU cũng đưa ra pipeline cho vectơ nhưng với khả năng xử lý vectơ như hiện tại thì sẽ khó xảy ra hiện tượng thắt nút chai. Các card đồ họa cấp thấp thường có từ 4-8 pixel pipeline, card tầm trung có 8-12 và các card cao cấp sẽ có từ 16 pipeline trở lên.

Xung nhịp nhanh hơn thì luôn tốt hơn, nhưng nếu phải chọn giữa số lượng pipeline hoặc tốc độ đồng hồ thì tốt hơn bạn nên chọn pipeline. Có 8 pipeline chạy ở tốc độ 400MHz sẽ tốt hơn nhiều chỉ có 4 pipeline chạy ở tốc độ 500MHz.

4. Hỗ trợ Windows Vista và Direct3D 10

Microsoft dự kiến sẽ tung ra phiên bản Windows Vista vào đầu năm 2007. Hệ điều hành mới này sẽ bao gồm cả DirectX10, một tập hợp các chức năng mà các ứng dụng thông qua nó để sử dụng các tài nguyên của máy, trong đó có card màn hình.

Phiên bản mới của DirectX kết hợp chặt chẽ với bản Direct3D mới được thiết kế nhằm phân phối, tổ chức hợp lý các pipeline giúp chuyển bớt công việc sang GPU và giảm tải cho CPU. Windows Vista sẽ vẫn làm việc với các card chỉ hỗ trợ DirectX9, tuy nhiên bạn cần có một card hỗ trợ DirectX10 để có được chất lượng tốt nhất.

Khoảng cuối năm nay, Nvidia và ATI sẽ cho ra mắt các card đồ họa hỗ trợ DX10, nhưng bạn không cần phải vội vàng vì các nhà phát triển game vẫn sẽ sử dụng khả năng tương thích ngược trong vài năm nữa. Tất cả các game, trong đó có những game như Halo3 và Shadowrun có thể chạy trên cả môi trường DX9 và DX10 mà không gặp phải vấn đề tương thích.

5. Thời gian phù hợp cho việc mua sắm

Cuộc cạnh tranh dữ dội giữa ATI va Nvidia đã khiến cho công nghệ 3D phát triển nhanh chóng. Các nhà sản xuất GPU cho ra đời một dòng chíp mới sau từ 12-18 tháng, giúp cho các card đồ họa ngày càng mạnh mẽ và nhiều chức năng hơn. Họ cũng tối ưu lại thiết kế để có thể làm mới và cho thêm chức năng vào sản phẩm chỉ vài tháng sau khi thiết kế ban đầu được công bố.

Có rất nhiều công nghệ rất đáng mong đợi như bộ tăng tốc đồ họa phân giải cao H.264 hay hỗ trợ mẫu đổ bóng tiên tiến… tuy nhiên sẽ cần vài năm để những công nghệ này trở nên phổ biến.

Thời điểm hiện tại sẽ luôn là thời điểm hợp lý để mua một card đồ họa mới nếu như bạn không có ý định mua loại card đứng “top” hiện nay. Giá của card đồ họa rớt rất nhanh sau khi các card mới ra đời, đưa giá của các dòng card yếu hơn về một mức giá chấp nhận được.

Bạn sẽ phí phạm rất nhiều tiền nếu mua một card đồ họa cao cấp ngay trước khi ATI hay Nvidia tung ra những GPU mới. Nhưng ngay cả khi đó bạn vẫn sẽ sở hữu một card đồ họa mạnh mẽ, có khả năng đáp ứng tất cả các game mà bạn muốn trong một thời gian dài.

6. Bạn không cần phải trả hơn 500 USD

Những card đồ họa cao cấp nhất có giá bán trên 500 USD nhưng bạn luôn tìm được những card đồ họa có hiệu năng cao ở mức giá 200-300 USD. Khoảng giá này luôn đưa tới tỷ suất hiệu năng trên giá tốt nhất bởi nó có sự kết hợp giữa những card tốt của thế hệ hiện tại và dòng card cao cấp của thế hệ trước.

Hãy kiểm tra số pipeline và xung nhịp của hai loại card này, nếu những con số là tương đương nhau thì tốt hơn nên chọn dòng card mới bởi chúng được hỗ trợ bởi những công nghệ cao và có thiết kế hiệu quả hơn.

7. Bạn có đủ năng lượng???

Yêu cầu về điện năng đang trở thành mối quan tâm lớn khi mà các card đồ họa ngày càng mạnh mẽ và cũng “ăn” nhiều điện hơn. Các nhà sản xuất đã in khuyến cáo về bộ nguồn (Power Supply Unit – PSU) cần có ngay trên hộp của card. Con số này thường lớn hơn con số tối thiểu một chút để đề phòng trường hợp PSU kém chất lượng hoặc hệ thống bị quá tải do sử dụng quá nhiều thiết bị. Card đồ họa tầm trung và cao cấp thường yêu cầu PSU từ 400-500W trong khi để thiết lập đồ họa kép như sử dụng CrossFire Radeon X1900 XTX cần bộ nguồn tối thiểu là 550W.

8. AGP hay PCI Express

Kể từ khi được giới thiệu hai năm trước, PCI Express đã thay thế AGP trở thành khe cắm đồ họa chuẩn trên các mainboard hiện nay. PCI Express đem tới băng thông cao gấp 2-4 lần so với AGP và hầu hết những card đồ họa mới đều sử dụng chuẩn PCI Express. Các nhà sản xuất GPU cũng đưa ra một vài dòng card sử dụng khe AGP như Nvidia GeForce 7800GS nhưng tất cả những thứ tuyệt nhất thì chỉ có trên PCI Express.

Nếu máy tính của bạn đã hơn 2 năm tuổi thì nó có thể sở hữu một khe cắm AGP. Nâng cấp lên PCI Express sẽ rất tốn kém bởi bạn sẽ phải thay thế toàn bộ Mainboard, CPU, RAM. Nhưng nếu như PC của bạn cũng thực sự đã hơn 2 năm tuổi và bạn muốn chơi những game sắp phát hành thì có lẽ đã đền lúc nghĩ tới việc nâng cấp toàn bộ hệ thống đi thôi.

9. SLI và CrossFire

Bạn sẽ phải nâng cấp lên PCI Express nếu muốn tận hưởng công nghệ đồ họa kép. Để làm một hệ thống đồ họa kép chạy và vận hành có hiệu quả là một công việc phức tạp và rắc rối. Bạn phải có đúng loại Mainboard, một cặp card đồ họa tương thích và một chiếc PSU “đủ sức qua cầu”.

Nvidia và ATI cùng đưa ra hai định dạng đồ họa kép và mỗi định dạng cần có một loại Mainboard riêng.

Nvidia giới thiệu SLI (Scalable link Interface) vào năm 2004 và từ đó đến nay đã xây dụng cả một chương trình chứng nhận SLI cho các thành phần chủ đạo như Mainboard, PSU, RAM… Bạn có thể kết hợp 2 card màn hình đã được chứng nhận tương thích với SLI của hai nhà sản xuất nhưng bắt buộc chúng phải sử dụng cùng loại GPU.

ATI đưa ra công nghệ đồ họa kép CrossFire của họ vào năm 2005. Cũng như với SLI, CrossFire yêu cầu một Mainboard phù hợp, RAM chất lượng và một PSU “trâu bò”. Kết hợp hai card của ATI hơi khó khăn hơn vì bạn cần phải kết hợp một card “CrossFire Edition” với một card “CrossFire Ready” để khiến chúng làm việc cùng nhau.

10. Hãy chắc rằng bạn đang mua một card đồ họa

Bạn là một người ham mê game và chơi những game mới nhất là thú vui của bạn. Vậy hãy cẩn thận với các hệ thống lắp ráp sẵn và chú ý tới phần tùy chọn đồ họa. Nếu như phần này chỉ có “Integrated graphics”, “video onboard” hay “đồ họa tích hợp” thì nó hoàn toàn không phù hợp với bạn đâu mà hãy tìm một hệ thống khác có card đồ họa thực sự.

Đồ họa tích hợp trên Mainboard chỉ thích hợp cho các ứng dụng đơn giản như Office, lướt Web hay nghe nhạc, xem phim. Chúng không đủ mạnh để đáp ứng những trò chơi ở độ phân giải cao và chất lượng tốt. Tất nhiên là nếu các game mà bạn chơi chỉ là Pikachu, bắn trứng hay dò mìn thì lại là một chuyện khác. Khi đó bạn hãy tiếp tục sống chung với card đồ họa cũ và có thể quên bài viết này đi.

Wirless Local Area Networks và Sức khoẻ con người

July 13, 2007

Do yêu cầu truy cập Internet và truyền dữ liệu trong môi trường di động, các mạng không dây cục bộ (WLAN – Wirless Local Area Network) đã ra đời và trở nên quen thuộc trong cuộc sống hàng ngày, số lượng điểm truy cập dịch vụ không dây ví dụ như trong các cơ quan, trường học, khu thương mại, quán cafe, nhà dân,… không ngừng tăng nhanh. 

 

 

Hình 1. Cấu hình WLAN kết nối với Internet và thiết bị di động (Laptop)

 

WLAN bao gồm các điểm truy cập (AP – Access Point) kết nối với mạng trục có dây (LAN) và liên lạc với các trạm di động (ví dụ như máy tính xách tay gắn Wi-Fi – Laptop) (Hình 1) trong vùng phủ sóng của tế bào (cell); các trạm di động không liên lạc với nhau; AP điều khiển Cell và lưu lượng đến mạng; các cell phủ sóng có thể chồng lấn lên nhau từ 10%-15% cho phép các máy trạm không mất liên lạc khi chuyển dịch từ vùng phủ sóng của cell này sang vùng phủ sóng của cell khác.  Trong trường hợp ở nơi nào có nhiều AP thì các trạm di động sẽ chọn AP nào có cường độ tín hiệu thu tốt nhất để liên lạc. Một AP nằm ở trung tâm một địa điểm nào đó có thể điều khiển và phân phối truy cập phù hợp với mạng trục có dây, nó ấn định địa chỉ và mức ưu tiên cho các máy trạm di động, giám sát lưu lượng mạng,…    

 

Các WLAN hiện nay sử dụng các máy phát tần số vô tuyến ở các AP công tác ở các tần số 900MHz theo chuẩn IEEE 806-11 có thể đạt tốc độ đến 2MB/s; chuẩn IEEE 806-11b phát ở tần số 2.4Ghz và tốc độ truyền dữ liệu có thể đạt 11MB/s; theo các chuẩn IEEE 802-11a, IEEE 802-11e và IEEE 802-11i làm việc ở tần số 5 GHz đạt được tốc độ truyền dữ liệu lên đến 54MB/s,… Các máy phát của điểm truy cập WLAN phát ra công suất rất phát thấp để liên lạc với máy tính xách tay có gắn Wi-Fi của người dùng hoặc các thiết bị có thể xách tay được. Có thể nói gần như các WLAN này sử dụng công nghệ Wi-Fi và được dùng phổ cập quen thuộc như các công nghệ không dây khác.

 

Mặc dù các máy phát của WLAN phát xạ công suất ở mức rất thấp nhưng một số người vẫn đặt câu hỏi: liệu các tín hiệu vô tuyến do các AP của WLAN dùng công nghệ Wi-Fi phát ra không gian có ảnh hưởng đến sức khoẻ hay không? Để trả lời câu hỏi đó ta hình dung nó gồm hai phần: một là, phơi nhiễm ở mức nào thì con người có thể cảm nhận được? năng lượng vô tuyến từ các WLAN có khả năng gây tác động xấu lên cơ thể con người không? 

 

      Để tìm hiểu và trả lời câu hỏi trên chúng ta phải xem xét công suất phát xạ và cơ chế phát sóng của các máy phát làm việc trong WLAN như sau: 

 

  1. Công suất phát xạ máy phát của các WLAN phát xạ ra không gian xung quanh với các mức công suất rất thấp vì thế có thể nói mức phơi nhiễm đối với người dùng máy tính trang bị Wi-Fi là rất rất thấp, những người đang có mặt hoặc hoạt động ở trong vùng WLAN làm việc nhưng không sử dụng máy tính có trang bị Wi-Fi thì mức phơi nhiễm còn thấp hơn nữa.  Mặt khác, theo cơ chế truyền sóng vô tuyến thì cường độ tín hiệu giảm theo bình phương khoảng cách từ người dùng đến anten máy phát của AP trong WLAN.  Theo các thuyết minh kỹ thuật của nhà sản xuất thì mức công suất cực đại đầu ra của các máy tính cá nhân trang bị Wi-Fi thấp hơn nhiều lần so với công suất đầu ra của tất cả các máy điện thoại di động cầm tay thông dụng hiện nay. 

 

  1. Máy phát trong các máy tính xách tay trang bị Wi-Fi và máy phát của các điểm truy cập làm việc theo nguyên tắc : chỉ phát ra công suất trong một khoảng thời gian rất ngắn và tại một thời điểm chỉ có một máy phát sóng làm việc (máy phát trong máy tính xách tay trang bị Wi-Fi  hoặc máy phát của điểm truy cập); WLAN được kết nối vào mạng có dây với lưu lượng mạng rất hạn chế, mạng sử dụng các cơ chế sửa lỗi,…  Tất cả những đặc tính trên làm cho khả năng phơi nhiễm năng lượng cao tần lên cơ thể là rất thấp và ở mức công suất rất thấp.

      

Tóm lại máy phát trong các máy tính cá nhân có trang bị Wi-Fi và điểm truy cập phát ra năng lượng cao tần không biến thiên (phát trong thời gian rất ngắn) do đó phơi nhiễm cao tần đối với cơ thế người dùng rất rất nhỏ so với phơi nhiễm do máy điện thoại di động cầm tay ở cùng một khoảng cách đối với người dùng.

 

Khoảng cách từ điểm truy cập (AP) đến người dùng lại xa hơn nhiều so với người dùng đến máy tính cá nhân vì vậy phơi nhiễm do AP tạo ra là vô cùng nhỏ. Các kết quả nghiên cứu chứng minh rằng, cường độ trường điện từ do các mạng Wi-Fi tạo ra nhỏ hơn rất nhiều so với trường điện từ phát ra từ các trạm gốc (BTS) thu phát của hệ thống thông tin di động, các máy phát của các đài phát thanh và truyền hình,…

 

Năm 2006, ông Kenneth R. Foster giáo sư chuyên ngành sinh vật kỹ thuật thuộc trường đại học Pennsylvania Hoa Kỳ đã khảo sát ảnh hưởng năng lượng trường điện từ lên cơ thể người ở trong các thành phố và vùng phụ cận thuộc bốn nước Hoa Kỳ, Pháp, Đức, Thuỵ Điển. Ông Kenneth R. Foster cùng các cộng sự đã thực hiện 356 phép đo khảo sát tín hiệu ở các băng tần cơ bản tại 55 vị trí bao gồm : các nhà dân, các khu thương mại, các cơ sở y tế như bệnh viện, các trường học, viện nghiên cứu và các khu vực công cộng khác.  Các phép đo được Giáo sư Kenneth R. Foster thực hiện tại các địa điểm công cộng gần với các điểm truy cập.  Các kết quả khảo sát của Giáo sư Kenneth R. Foster được công bố chi tiết, công khai trên tạp chí Vật lý Y tế (số 92 trang 280-289; năm 2007)  cho thấy chúng đều nằm rất xa dưới mức các Giới hạn An toàn Cao tần Quốc tế cho phép được Viện các kỹ sư Điện và Điện tử (IEEE 2002- Institute of Electrical and Electronics Engineers) và Tổ chức Bảo vệ Bức xạ Không ion hoá Quốc tế (ICNIRP – International Commission on Nonionizing Radiation Protection) đưa ra năm 2002. Các giới hạn an toàn cao tần này được thiết kế và xác lập để bảo con người khỏi ảnh hưởng của tất cả các năng lượng cao tần trong không gian mà loài người đã biết từ các nguồn bức xạ vô tuyến tự nhiên và nhân tạo.  Trong hầu hết các trường hợp khảo sát, các kết quả đo khảo sát do Giáo sư Kenneth R. Foster và các cộng sự thu được đều thấp hơn rất xa các nguồn năng lượng cao tần ở gần đó bao gồm cả các trạm thu phát gốc của hệ thống điện thoại di động và các máy điện thoại di động cầm tay (công suất phát từ 0.2-0.6W).

 

  Các mối quan tâm về khả năng ảnh hưởng đến sức khoẻ do phơi nhiễm từ các nguồn bức xạ điện từ có cường độ trường ở mức thấp trong cuộc sống cộng đồng đã được nghiên cứu thống kê trên nhiều người trong nhiều năm có liên hệ đến các công nghệ khác có sử dụng năng lượng cao tần khác.  Để giải quyết các mối quan tâm đó, các tổ chức y tế trên khắp thế giới trong nhiều năm qua đã xem xét liên tục, nhiều lần các tài liệu khoa học, các kết quả thí nghiệm trong một thời gian dài và tìm ra rằng: Sức khoẻ con người không bị ảnh hưởng khi sống và làm việc trong môi trường có bức xạ dưới mức Giới hạn An toàn Cao tần quốc tế. Một ví dụ điển hình, năm 2006 Tổ chức Y tế Thế giới một lần nữa tuyên bố khẳng định: “Không có các ảnh hưởng sức khoẻ được nhận biết do phơi nhiễm trong trường điện từ do các trạm gốc thông tin di động và các mạng không dây (WHO 2006)”.

            

Tài liệu tham khảo

[1]. Kenneth R. Foster Radiofrequency exposure from Wireless LANs. Health Physics 92:280-289; 2007.

[2]. International Commission on Non-Ionizing Radiation Protection. General approach to protection against non-ionizing radiation. ICNIRP Statement in Health Physics 82:540-548; 2002.

[3]. World Health Organization. Electromagnetic fields and public health: Base stations and wireless technologies; May 2006. WHO Fact Sheet. Available at: http://www.who.int/mediacentre/factsheets/fs30