Сетевое программирование в .NET. Расшифровка IP-адреса (IP address specification). Обеспечение надежности доставки пакетов, страница 30

¨  Добавьте элемент RichTextBox с именем richText и расположите его под окном браузера. Его свойство Dock тоже установите в значение Top.

Для этого надо освободить ме

Using Connectionless Sockets

Because SOCKET DGRAM-type sockets use the UDP protocol, no connection information is required to be sent between network devices. Because of this, it is often difficult to determine which device is acting as a “server”, and which is acting as a “client”. If a device is initially waiting for data from a remote device, the socket must be bound to a local address/port pair using the bind() function. Once this is done the device can send data out from the socket, or receive incoming data from the socket. Because the client device does not create a connection to a specific server address, the connect() function need not be used for the UDP client program. Figure 3.3 illustrates the function sequence used for programming a connectionless socket.

Non-blocking I/O Methods

One drawback to the standard Unix network programming model is that the I/O functions (the functions used for sending and receiving data) block if they cannot be processed immediately. Blocking refers to stopping execution of the program and waiting for a specific statement to complete. For example, when a program gets to a recv() function, it will stop and wait until data is available on the socket to read. In effect, the recv() function blocks further execution of the program until data is present on the socket. If the remote device does not send any data, the program does not continue.

Although this principle may work fine for a single-connection client/server program where you can control the sending and receiving data patterns, it causes a problem for any type of program that must continue to process other events despite errors in sending or receiving data. There are two techniques that can be used to solve this problem: using non-blocking sockets or using socket multiplexing.

Non-blocking Sockets

A simple rudimentary solution for preventing undesirable blocking is to set a socket to not block when an I/O function is called. The non-blocking feature can be set as a special socket option on the socket using the fcntl() function. The fcntl() function is used to perform miscellaneous low-level operations on file descriptors. Setting blocking on a socket is one of those operations. Here is the format of the fcntl() function:

int fcntl(int fd, int cmd, int arg)

The fd parameter should be an open file descriptor (or socket, in this case). The cmd parameter specifies what operation will be done on the file descriptor. For example, the command F_SETFL is used to read or set a file descriptor’s flag options. The arg parameter is used to specify the flag to set (or query). So, to set a socket to non-blocking mode, you would use the following:

int newsocket;

newsocket = socket(PF_INET, SOCKET_STREAM, 0);

fcntl(newsocket, F_SETFL, O_NONBLOCK);

Here the O_NONBLOCK flag indicates that the socket should be set to non-blocking mode. Whenever a recv() function is performed on the newsocket socket, the program will not wait for data. If no data is immediately present, the recv() function will return a value of –1, and the Unix errno value would be set to EWOULDBLOCK. Using non-blocking sockets, you can poll any open socket to look for incoming data or to determine if it is ready for outgoing data.

Multiplexed Socket

Another solution to the socket blocking problem uses the select() function to multiplex all the active sockets. The select() function lets you watch multiple sockets for events (such as data to be read from or written to the socket), and process only the sockets that need to be processed. Sockets without any pending events are skipped so they won’t block the program execution. The format of the select() function is as follows:

int select(int numfd, fd_set *readfds, fd_set *writefds,

fd_set *exceptfds, struct timeval *timeout)