BSD套接字(BSD Sockets)

来源:互联网 发布:航天信息软件发票打印 编辑:程序博客网 时间:2024/05/16 06:44

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,..协议)

 

 

 

 

 

 

 

 

   

 

 

 

    

 

0 0