System Development
 

システム開発 - 分析:setsockopt()はソケットネットワークプログラミング()に堅牢性を向上させるために

1。状態が(通常はポート番号と識別子を区別する)確立されたソケット内にすでに存在する場合を呼び出す
がclosesocket(通常はすぐがTIME_WAITのプロセスをシャットダウンしていない)ソケットの再利用後も継続する:
BOOL bReuseaddr=TRUE;




2。あなたが強制的にsoketの接続状態になっている場合、closesocketを呼び出した後に経験をしない閉じる
TIME_WAITのプロセス:
BOOL bDontLinger = FALSE;
setsockoptの(秒、をSOL_SOCKET、SO_DONTLINGER、(const char *)を&bDontLingerは、sizeof(ブール値));




int型nNetTimeout = 1000; / / 1秒
/ /時刻を送信
setsockoptの(ソケット、SOL_S0CKET、SO_SNDTIMEO、(char *)を&nNetTimeoutは、sizeof(int型));
/ /時刻を受信する
setsockoptの(ソケット、SOL_S0CKET、SO_RCVTIMEOは、(char *)を&nNetTimeoutは、sizeof(int型));

(非同期)、システムのデフォルト状態は8688回送信し、受信バイト(約8.5K)、データを送信する実際のプロセスで
そして、大きく、あなたは()、recv()のSENDを送信し、継続的なサイクルを受信しないようにソケットバッファを設定することができますよりもデータが表示されます:
/ /受信バッファ

setsockoptの(秒、をSOL_SOCKET、SO_RCVBUFは、(const char *)を&nRecvBufは、sizeof(int型));
/ /バッファを送信
int型nSendBuf = 32 * 1024; / / 32Kに設定
setsockoptの(秒、をSOL_SOCKET、SO_SNDBUFを、(const char *)を&nSendBufは、sizeof(int型));
5。データを送信する場合は、私が影響を受けるソケットバッファにシステムのコピーでバッファを経験していない願っています

int nZero=0;
setsockoptの(ソケット、SOL_S0CKET、SO_SNDBUFを、(char *)を&nZeroは、sizeof(nZero));
6。同上recvをの()は、これらの関数(デフォルトでは、システムバッファにソケットバッファの内容をコピーすることです)を完了する:
int nZero=0;
setsockoptの(ソケット、SOL_S0CKET、SO_RCVBUFは、(char *)を&nZeroは、sizeof(int型));

BOOL bBroadcast=TRUE;
setsockoptの(秒、をSOL_SOCKET、SO_BROADCASTを、(const char *)を&bBroadcastは、sizeof(ブール値));
8。ソケットができる非connect()のプロセスでは、ブロッキングモードの場合、クライアントは、サーバープロセスに接続する
()accpetまでconnect()の遅延時間を設定するには(この中でのみプロセスを設定するには、この関数が呼び出されます非大幅にブロッキング
関数の呼び出しをブロックする役割)が役割ではない
BOOL bConditionalAccept=TRUE;
setsockoptの(秒、をSOL_SOCKET、SO_CONDITIONAL_ACCEPT、(const char *)を&bConditionalAcceptは、sizeof(ブール値));

一般的には、"オフ落ち着いて"シャットダウン(秒、SD_BOTH)の測定データは確かに、特定の対応するプログラムを設定する方法が失われ、
アプリケーションの要件(すなわち、近くのソケットの後に送信されるデータには終わりを受けて)?
struct linger {
u_short l_onoff;
u_short l_linger;
};
linger m_sLinger;
m_sLinger.l_onoffは、= 1; / /(がclosesocket()を呼び出しが、時の滞在許可は、データの送信が完了したがある)

m_sLinger.l_linger = 5; / /(5秒間の滞在を許可する)
(sは、をSOL_SOCKET、SO_LINGERは、(const char *)を&m_sLingerには、sizeof(長居))でsetsockopt;
注:1。滞在は、ノンブロッキングソケットに対して設定された時間遅延では、非常に有用ではなく、良いとは2。あなたがSO_DONTLINGER設定する必要はありませんSO_LINGERは、セットはl_onoff = 0が発生する場合;
10。また、SDIのプログラムに以下のダイアログと比較するには、デバッグ情報をソケットを記録することができます:
(本機能のテストを行った昔、デバッグ情報をソケットを含む、保存することができます場合によって確立されたパラメータ

BOOL bDebug=TRUE;
setsockoptの(秒、をSOL_SOCKET、SO_DEBUG、(const char *)を&bDebugは、sizeof(ブール値));
11。追加:多くの場合でsetsockopt()を介してバッファサイズを設定しますが、それは、データ伝送のための需要を満たすことができない、
私の習慣は、ネットワークのバッファ処理は、メモリの動的割り当てを持つクラスの取引を記述することですが、一般的には、ネットワークバッファ、メモリの動的割り当てを扱うクラスを作成することです。今、私はこのクラスを記述します、我々が支援することを望む:

//==============================================================================
/ /主に送信し、ネットワーク内のデータを受信バッファのバイナリデータ、
/ /ソースコードを書き換えるための青写真としてMFC CStringクラスは、CStringの使用で作られてCNetIOBufferに似ています
/ /しかしCNetIOBufferは、純粋なバイナリデータに格納されている'\ 0'ではない、それは最後のマークとして。
/ /データの長さはGetLengthの()は、バッファのアドレスは、演算子LPBYTEを介して取得することができますを取得することができます。
//==============================================================================
// Copyright (c) All-Vision Corporation. All rights reserved.
// Module: NetObject
// File: SimpleIOBuffer.h
// Author: gdy119
// Email :
// Date: 2004.11.26
//==============================================================================
// NetIOBuffer.h
#ifndef _NETIOBUFFER_H
#define _NETIOBUFFER_H
//=============================================================================
#define MAX_BUFFER_LENGTH 1024*1024
//=============================================================================
/ /メインデータは、ネットワークを処理するためのバッファ
class CNetIOBuffer
{
protected:
LPBYTE m_pbinData;
int m_nLength;
int m_nTotalLength;
CRITICAL_SECTION m_cs;
void Initvalibers();
public:
CNetIOBuffer();
CNetIOBuffer(const LPBYTE lbbyte, int nLength);
CNetIOBuffer(const CNetIOBuffer&binarySrc);
virtual ~CNetIOBuffer();
//=============================================================================
BOOL CopyData(const LPBYTE lbbyte, int nLe

int nZero=0;
setsockoptの(ソケット、SOL_S0CKET、SO_SNDBUFを、(char *)を&nZeroは、sizeof(nZero));
私は何人かの友人は、前述のを覚えて、ソケットは、成功したが、送信のみ内部のデータバッファに送信され、実際に物理デバイスを送信されていません。シールドは、送信することをした後、このステートメントを使用してバッファを送信され、0に設定されているバッファは、かつては、データが^ _ ^さんから彼の方法で送信されていることを確認する(もちろん、ブロッキングソケットのためのものです)送り返すように行うシステムのパフォーマンスに影響を与える可能性があります
setoptsock()は、この関数は、ポートの多重化を設定するには、それは別のモデルの数は、プログラムに害が発生しない非常にバインドするのは簡単です。

======================================
Example Code
The following example demonstrates the setsockopt function.
#include <stdio.h>
#include "winsock2.h"
void main() {
//
// Declare variables
WSADATA wsaData;
SOCKET ListenSocket;
sockaddr_in service;
//
// Initialize Winsock
int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
if( iResult != NO_ERROR )
printf("Error at WSAStartup\n");
//
// Create a listening socket
ListenSocket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if (ListenSocket == INVALID_SOCKET) {
printf("Error at socket()\n");
WSACleanup();
return;
}
//
// Bind the socket to the local IP address
// and port 27015
hostent* thisHost;
char* ip;
u_short port;
port = 27015;
thisHost = gethostbyname("");
ip = inet_ntoa (*(struct in_addr *)*thisHost->h_addr_list);
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr(ip);
service.sin_port = htons(port);
if ( bind( ListenSocket,(SOCKADDR*) &service, sizeof(service) ) == SOCKET_ERROR ) {
printf("bind failed\n");
closesocket(ListenSocket);
return;
}
//
// Initialize variables and call setsockopt.
// The SO_KEEPALIVE parameter is a socket option
// that makes the socket send keepalive messages
// on the session. The SO_KEEPALIVE socket option
// requires a boolean value to be passed to the
// setsockopt function. If TRUE, the socket is
// configured to send keepalive messages, if FALSE
// the socket configured to NOT send keepalive messages.
// This section of code tests the setsockopt function
// by checking the status of SO_KEEPALIVE on the socket
// using the getsockopt function.
BOOL bOptVal = TRUE;
int bOptLen = sizeof(BOOL);
int iOptVal;
int iOptLen = sizeof(int);
if (getsockopt(ListenSocket, SOL_SOCKET, SO_KEEPALIVE, (char*)&iOptVal, &iOptLen) != SOCKET_ERROR) {
printf("SO_KEEPALIVE Value: %ld\n", iOptVal);
}
if (setsockopt(ListenSocket, SOL_SOCKET, SO_KEEPALIVE, (char*)&bOptVal, bOptLen) != SOCKET_ERROR) {
printf("Set SO_KEEPALIVE: ON\n");
}
if (getsockopt(ListenSocket, SOL_SOCKET, SO_KEEPALIVE, (char*)&iOptVal, &iOptLen) != SOCKET_ERROR) {
printf("SO_KEEPALIVE Value: %ld\n", iOptVal);
}
WSACleanup();
return;
}
Notes for IrDA Sockets
Keep in mind the following:
The Af_irda.h header file must be explicitly included.
IrDA provides the following settable socket option:
Value Type Meaning
IRLMP_IAS_SET *IAS_SET Sets IAS attributes
The IRLMP_IAS_SET socket option enables the application to set a single attribute of a single class in the local IAS. The application specifies the class to set, the attribute, and attribute type. The application is expected to allocate a buffer of the necessary size for the passed parameters.
IrDA provides an IAS Database that stores IrDA-based information. Limited access to the IAS Database is available through the windows Sockets 2 interface, but such access is not normally used by applications, and exists primarily to support connections to non-windows devices that are not compliant with the windows Sockets 2 IrDA conventions.
The following structure, IAS_SET, is used with the IRLMP_IAS_SET setsockopt option to manage the local IAS Database:
typedef struct _IAS_SET {
char irdaClassName[IAS_MAX_CLASSNAME];
char irdaAttribName[IAS_MAX_ATTRIBNAME];
u_long irdaAttribType;
union
{
LONG irdaAttribInt;
struct
{
u_short Len;
u_char OctetSeq[IAS_MAX_OCTET_STRING];
} irdaAttribOctetSeq;
struct
{
u_char Len;
u_char CharSet;
u_char UsrStr[IAS_MAX_USER_STRING];
} irdaAttribUsrStr;
} irdaAttribute;
} IAS_SET, *PIAS_SET, FAR *LPIAS_SET;
The following structure, IAS_QUERY, is used with the IRLMP_IAS_QUERY setsockopt option to query a peer's IAS Database:
typedef struct _windows_IAS_QUERY {
u_char irdaDeviceID[4];
char irdaClassName[IAS_MAX_CLASSNAME];
char irdaAttribName[IAS_MAX_ATTRIBNAME];
u_long irdaAttribType;
union
{
LONG irdaAttribInt;
struct
{
u_long Len;
u_char OctetSeq[IAS_MAX_OCTET_STRING];
} irdaAttribOctetSeq;
struct
{
u_long Len;
u_long CharSet;
u_char UsrStr[IAS_MAX_USER_STRING];
} irdaAttribUsrStr;
} irdaAttribute;
} IAS_QUERY, *PIAS_QUERY, FAR *LPIAS_QUERY;
Many SO_ level socket options are not meaningful to IrDA. Only SO_LINGER is specifically supported.
Note setsockopt must be called before bind on windows NT 4.0, windows 95, and windows 98 platforms.
Requirements
Client Requires windows XP, windows 2000 Professional, windows NT Workstation, windows Me, windows 98, or windows 95.
Server Requires windows Server 2003, windows 2000 Server, or windows NT Server.
Header Declared in Winsock2.h.
Library Link to Ws2_32.lib.
DLL Requires Ws2_32.dll.
Trackback: [url][/url]