天天看點

BSD套接字(BSD Sockets)

BSD Sockets 使用的最廣泛的網絡程式程式設計方法,主要用于應用程式的編寫,用于網絡上主機與主機之間的互相通信.

UNIX,Linux,VxWorks均支援BSD Sockets,Windows的Winsock基本上是來自BSD Sockets

Socket分為Stream Sockets和Data Sockets.

Stream Sockets是可靠性的雙向資料傳輸用TCP,如HTTP,FTP等

Data Sockets是不可靠連接配接用UDP,如多點廣播,DHCP,SNMP,RIP等.

 

  • TCP伺服器端和一個TCP用戶端通信的程式過程
  伺服器 客戶機

建立一個Socket

sFd =socket (AF_INET, SOCK_STREAM, 0)

把Socket和本機的IP,TCP口綁定

bind (sFd, (struct sockaddr *) &serverAddr, sockAddrSize)

為客戶連接配接建立等待隊列

listen (sFd, SERVER_MAX_CONNECTIONS)

這裡循環等待,如有客戶連接配接請求,則接受客戶機連接配接要求

accept (sFd, (struct sockaddr *) &clientAddr, &sockAddrSize))

接受客戶機發來的資訊

fioRead (sFd, (char *) &clientRequest, sizeof (clientRequest)))

給客戶機發資訊

write (sFd, replyMsg, sizeof (replyMsg))

關閉Socket,通信終止

close (sFd)

 

兩個淺藍色的函數是兩個Sockets的握手函數,即在這裡建立連接配接

建立一個Socket

sFd =socket (AF_INET, SOCK_STREAM, 0)

注意:用戶端不需要綁定,因為TCP口是動态的.

向伺服器端發送連接配接請求,并在這裡等待回應,如收到回應則向下執行

connect (sFd, (struct sockaddr *) &serverAddr, sockAddrSize)

伺服器接受連接配接請求後,讀伺服器發過來的資訊

read(sFd,buffer,20)

向伺服器發資訊

write(sFd, buffer, 20);

關閉Sockets

close (sFd)

 

  • UDP伺服器端和一個UDP用戶端通信的程式過程
  伺服器 客戶機

建立一個Socket

sFd =socket (AF_INET, SOCK_DGRAM, 0)

把Socket和本機的IP,TCP口綁定

bind (sFd, (struct sockaddr *) &serverAddr, sockAddrSize)

不需要建立等待隊列

 

這裡循環等待,如有客戶連接配接則接受,并讀取客戶發來的資訊

recvfrom (sFd, (char *) &clientRequest, sizeof (clientRequest), 0, (struct sockaddr *) &clientAddr, &sockAddrSize)

關閉Socket,通信終止

close (sFd)

 

 

 

 

 

這裡不建立連接配接,隻是資料收發

<----------

 

建立一個Socket

sFd =socket (AF_INET, SOCK_DGRAM, 0)

注意:用戶端不需要綁定,因為UCP口是動态的.

向伺服器端發送連接配接請求和資訊,這裡不等待伺服器的響應

sendto (sFd, (caddr_t) &myRequest, sizeof (myRequest), 0, (struct sockaddr *) &serverAddr, sockAddrSize)

關閉Sockets

close (sFd)

UDP廣播包程式示例

發送UDP廣播包,查找本地網絡中所有運作SNMP服務裝置的IP資訊。

winsock, win32控制台程式。

#define SNMP_PORT 161

void SearchIP_In_LAN() 

WSADATA wsaData; 

SOCKET sockListener;

SOCKADDR_IN saUdpCli,saUdpServ;

BOOL fBroadcast = TRUE;

char sendBuff[40]= //SNMP查詢包内容

'\x30','\x26','\x02','\x01','\x00', 

'\x04','\x06','\x70','\x75','\x62', 

'\x6c','\x69','\x63','\xa0','\x19', 

'\x02','\x01','\x03','\x02','\x01', 

'\x00','\x02','\x01','\x00','\x30', 

'\x0e','\x30','\x0c','\x06','\x08', 

'\x2b','\x06','\x01','\x02','\x01', 

'\x01','\x01','\x00','\x05','\x00' 

}; 

char recvBuff[600]; 

int nSize,err,timeoutnum = 1;;

ULONG HostIpAddr;

int rv; 

int ncount=0; 

if(WSAStartup(MAKEWORD( 2, 2),&wsaData)!=0) 

{

printf("Winsocket start error!\n");

return; 

}

sockListener=socket(AF_INET,SOCK_DGRAM,0); 

err = setsockopt ( sockListener,

SOL_SOCKET,

SO_BROADCAST, 

(CHAR *)&fBroadcast,

sizeof ( BOOL )); 

if ( SOCKET_ERROR == err ) return ;

int TimeOut=10000;

err = setsockopt ( sockListener, 

SOL_SOCKET,

SO_RCVTIMEO,

(CHAR *) &TimeOut,

sizeof (TimeOut)

);

if ( SOCKET_ERROR == err ) return ;

saUdpCli.sin_family = AF_INET; 

saUdpCli.sin_port = htons(0); 

saUdpCli.sin_addr.s_addr = htonl(INADDR_ANY); 

if(bind( sockListener, (SOCKADDR *)&saUdpCli, sizeof(SOCKADDR_IN))!=0) 

printf("Can't bind socket to local port!Program stop.\n");

return; 

err = gethostname(recvBuff,sizeof(recvBuff));

if ( SOCKET_ERROR == err )

return ;

struct hostent *hp = gethostbyname(recvBuff);

if (!hp) return ;

saUdpServ.sin_family = AF_INET; 

memcpy(&(saUdpServ.sin_addr),hp->h_addr,hp->h_length);

HostIpAddr=ntohl(saUdpServ.sin_addr.s_addr);

saUdpServ.sin_addr.s_addr = htonl ( INADDR_BROADCAST ); 

saUdpServ.sin_port = htons (SNMP_PORT);

nSize = sizeof ( SOCKADDR_IN ); 

if((rv = sendto ( sockListener,

sendBuff,

sizeof(sendBuff),0,

(SOCKADDR *) &saUdpServ,

sizeof ( SOCKADDR_IN )))==SOCKET_ERROR) 

printf("Send error!\n");

closesocket(*((SOCKET*)sockListener)); 

return; 

printf("Send successful!\n");

do // waiting to receive

{

if((rv=recvfrom ( sockListener,

recvBuff,sizeof(recvBuff),0,

(SOCKADDR *) &saUdpCli,&nSize))==SOCKET_ERROR) 

if(WSAGetLastError()==WSAETIMEDOUT)

{

if (timeoutnum > 6 ) //Wait for 1 minute.

break;

else

timeoutnum++;

}

}

else

{

CString Ip(inet_ntoa ( saUdpCli.sin_addr ));

printf("\t IP Adress-> %s ",Ip);

}while(TRUE);

closesocket(*((SOCKET*)sockListener)); 

return ;

}

 

網絡軟體設計框圖(個人了解,僅供參考)

 

  • 裝置管理服務軟體架構

PC端(Windows NT,UNIX,Novell...平台)

管理伺服器(HTTP,FTP...Server)

伺服器程式
程式接收使用者請求,向下發送 從下接收處理結果,發送給使用者

|

|

|

v

^

|

|

|

通信方式:Socket, Namedpipe等

||

||

||

背景核心程式
處理請求,接收發送資料
SNMP客戶

<=============>

Internet(HTTP,..協定)

如使用者PC缺少相應驅動,伺服器會動态為使用者PC加載安裝

 

 

 

 

 

Internet

(SNMP協定)

<=============>

終端PC使用者

(IE浏覽器...)

 

 

 

 

 

 

 

 

網絡裝置

(嵌入式作業系統)

SNMP伺服器

 

  • 資訊家電(IA)的架構

 

網絡裝置(嵌入式作業系統平台)
嵌入式伺服器(Embedded Web Server, HTTP, FTP... )
伺服器程式
程式接收使用者請求,向下發送 從下接收處理結果,發送給使用者

|

|

|

v

^

|

|

|

通信方式: Socket, Namedpipe等

||

||

||

背景核心程式
處理請求,接收發送資料
||
嵌入式系統SNMP接口
||
裝置SNMP(MIB)

<===========>

Internet(HTTP,..協定)

 

 

 

 

 

 

 

 

終端PC使用者

(IE浏覽器...)

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 無線移動通信的架構

 

基站無線發送接收裝置(無線通信協定)
接收端處理軟體
程式接收處理資料標頭,實質符合Internet傳輸的某種協定(如X.25),放到Internet上 從下接收資料包,加上自自己無線通信協定的標頭,無線發出給使用者終端

||

||

通信方式:Internet(雙向)
X.25,ATM....等協定

||

||

網關(GATEWAY)
處理資料包的内容,相關内容讀取存放資料庫

||

||

資料庫

||

||

HTTP協定

對資料庫操作,添加,删除,列印... 

終端PC(IE浏覽器)

<============>

無線通信協定

(Mobitex或DataTAC,..協定)