您的位置:首页 > 其它

用Socket在局域网内进行广播

2013-03-06 10:12 190 查看
服务器和客户机采用Socket编程。

问题1:服务器进入侦听状态,但是此时客户端并不知道服务器的地址。我该如何做?

问题2:我想使客户端先发出一个广播,服务器接受广播后给客户机发送自己的Ip等信息。

接着再建立Socket通讯。这样对吗?

问题3:是不是进行广播必须是数据报SOCK_DGRAM

问题4:是不是通讯的双方必须都是数据流或数据报?如果服务器是数据流SOCK_STREAM套接字,而客户机是数据报套接字就不能够通讯?

1、用广播(或组播)方式,客户端不需道服务器的地址,初始化时用程序建立一个新的广播地址。

2、用广播(或组播)方式,可直接收发数据。不用侦听。

3、是;

4、只要是数据就行。

例子:

[cpp] view
plaincopy

// MSGSocket.cpp : implementation file

//

#include "stdafx.h "

//#include "AV8Rcvr.h "

#include "MSGSocket.h "

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

/////////////////////////////////////////////////////////////////////////////

// CMSGSocket

CMSGSocket::CMSGSocket()

{

bForceNoLoopback = FALSE;

bDataReceived = false; /* Variable defined for this project. Not necessarily part of CMsocket */

number=0;

for(int i=0;i <40;i++)

{

ready[i]=false;

}

number=0;

newfile=false;

receivenumber=0;

filename= " ";

}

CMSGSocket::~CMSGSocket()

{

}

// Do not edit the following lines, which are needed by ClassWizard.

#if 0

BEGIN_MESSAGE_MAP(CMSGSocket, CSocket)

//{{AFX_MSG_MAP(CMSGSocket)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

#endif // 0

/////////////////////////////////////////////////////////////////////////////

// CMSGSocket member functions

BOOL CMSGSocket::CreateSocket(LPCTSTR strGroupIP, UINT nGroupPort)

{

/* Create socket for receiving packets from multicast group */

LeaveGroup();

//if(!Create(nGroupPort, SOCK_DGRAM, FD_READ|FD_WRITE)) //CAsyncSocket

if(!Create(nGroupPort, SOCK_DGRAM, NULL)) //CSocket

{

AfxMessageBox( "建立连接时出错,检查该频道是否已被别的窗口占用! ");

return FALSE;

}

BOOL bMultipleApps = TRUE; /* allow reuse of local port if needed */

SetSockOpt(SO_REUSEADDR, (void*)&bMultipleApps, sizeof(BOOL), SOL_SOCKET);

/* Fill m_saHostGroup_in for sending datagrams */

memset(&m_saHostGroup, 0, sizeof(m_saHostGroup));

m_saHostGroup.sin_family = AF_INET;

m_saHostGroup.sin_addr.s_addr = inet_addr(strGroupIP);

m_saHostGroup.sin_port = htons((USHORT)nGroupPort);

/* Join the multicast group */

m_mrMReq.imr_multiaddr.s_addr = inet_addr(strGroupIP); /* group addr */

m_mrMReq.imr_interface.s_addr = htons(INADDR_ANY); /* use default */

if(setsockopt(m_hSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char FAR *)&m_mrMReq, sizeof(m_mrMReq)) < 0)

{

AfxMessageBox( "CreateReceivingSocket failed ");

return FALSE;

}

return TRUE;

}

void CMSGSocket::OnReceive(int nErrorCode)

{

::SetActiveWindow(AfxGetApp()-> m_pMainWnd-> m_hWnd);

//AfxMessageBox( "MSG收到数据! ");

//return;

int nError = ReceiveFrom (&msg_commanddata,sizeof(csock_data), m_strSendersIP, m_nSendersPort);

if(nError == SOCKET_ERROR)

AfxMessageBox( "Error receiving data from the host group ");

else

{

if (!bForceNoLoopback || (bForceNoLoopback && !(m_strSendersIP == m_strLocalIP && m_nSendersPort == m_nLocalPort)))

{

//lyksetdata1(3);

//AfxMessageBox( "MSG收到数据! ");

::PostMessage(GetActiveWindow( ),WM_COMMAND,WM_RECEIVEMSG,(LPARAM)0);

}

}

CSocket::OnReceive(nErrorCode);

}

BOOL CMSGSocket::LeaveGroup()

{

if(setsockopt (m_hSocket, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char FAR *)&m_mrMReq, sizeof(m_mrMReq)) < 0)

return FALSE;

Close(); // Close receving socket

return TRUE;

}

/*

BOOL CMSGSocket::Send(const void* strMessage, int nSize)

{

//CString str=strMessage;

//AfxMessageBox(str);

if(SendTo(strMessage, nSize, (SOCKADDR*)&m_saHostGroup, sizeof(SOCKADDR), 0) == SOCKET_ERROR)

return FALSE;

else

return TRUE;

}

*/

BOOL CMSGSocket::Send(csock_data m_data1)

{

if(SendTo(&m_data1, sizeof(csock_data), (SOCKADDR*)&m_saHostGroup, sizeof(SOCKADDR), 0) == SOCKET_ERROR)

{

return FALSE;

}

else

{

//AfxMessageBox( "MSGSend! ");

return TRUE;

}

}

BOOL CMSGSocket::TextSend(CString str)

{

CString st=str;

st+= "/@&/ ";

//BOOL bo=Send(st, st.GetLength()+1);

return 0;

}

BOOL CMSGSocket::GetMaker(void)

{

return bDataReceived;

}

void CMSGSocket::SetMaker(BOOL da)

{

bDataReceived=da;

//ready[number]==da;

}

void CMSGSocket::Init(void)

{

bForceNoLoopback = FALSE;

bDataReceived = false; /* Variable defined for this project. Not necessarily part of CMSGSocket */

number=0;

for(int i=0;i <40;i++)

{

ready[i]=false;

}

}

BOOL CMSGSocket::SendFile(CString filename)

{

return 0;

}

void CMSGSocket::ReadFile()

{

}

BOOL CMSGSocket::SendData(SOCKET_STREAM_FILE_INFO m_data1)

{

//AfxMessageBox( "send........ ");

if(SendTo(&m_data1, sizeof(SOCKET_STREAM_FILE_INFO), (SOCKADDR*)&m_saHostGroup, sizeof(SOCKADDR), 0) == SOCKET_ERROR)

{

//AfxMessageBox( "send false ");

return FALSE;

}

else

{

//AfxMessageBox( "send ok ");

return TRUE;

}

}

[cpp] view
plaincopy

#if !defined(AFX_MSGSocket_H__257F140C_C139_4112_BACA_2C16C0F155B8__INCLUDED_)

#define AFX_MSGSocket_H__257F140C_C139_4112_BACA_2C16C0F155B8__INCLUDED_

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

// MSGSocket.h : header file

//

/////////////////////////////////////////////////////////////////////////////

// CMSGSocket command target

class CMSGSocket : public CSocket

{

// Attributes

public:

char m_strBuffer[32768];

char m_strBuffer1[32768];

char m_strBuffer2[32768]; // Receiving buffer for the packet that has arrived

SOCKADDR_IN m_saHostGroup; // SOCKADDR structure to hold IP/Port of the Host group to send data to it

ip_mreq m_mrMReq; // Contains IP and interface of the host group

UINT m_nSendersPort; // Holds Port No. of the socket from which last packet was received

CString m_strSendersIP; // Hold IP of the socket from which the last packet was received

UINT m_nLocalPort; // Ephemeral port number of the sending port

CString m_strLocalIP; // IP Address of the local host or your machine

BOOL bForceNoLoopback; // If interface does not support lopback and the service is required, the bool is set to true

BOOL bDataReceived;

BOOL LeaveGroup();

//BOOL Send(const void*, int);

BOOL Send(csock_data m_data1);

BOOL CreateSocket(LPCTSTR, UINT);

BOOL ready[40];

int number;

CString text;

////////////////

csock_data msg_commanddata;

BOOL newfile;

DWORD fileID;

DWORD receivenumber;

CString filename;

BOOL GetMaker(void);

void SetMaker(BOOL da);

void ReadFrom(void);

void Init(void);

BOOL TextSend(CString text);

BOOL SendFile(CString filename);

void ReadFile(void);

BOOL SendData(SOCKET_STREAM_FILE_INFO m_data1);

/////////////////////

////////////////

HINSTANCE glib;

LYKGETDATA lykgetdata1;

LYKSETDATA lyksetdata1;

// Operations

public:

CMSGSocket();

virtual ~CMSGSocket();

// Overrides

public:

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CMSGSocket)

public:

virtual void OnReceive(int nErrorCode);

//}}AFX_VIRTUAL

// Generated message map functions

//{{AFX_MSG(CMSGSocket)

// NOTE - the ClassWizard will add and remove member functions here.

//}}AFX_MSG

// Implementation

protected:

};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_MSGSocket_H__257F140C_C139_4112_BACA_2C16C0F155B8__INCLUDED_)

用法是:

void CMainFrame::SendMSG(int pcommand,int pmsg)

{

if(!MSG_Socket.CreateSocket( "234.5.6.7 ", 206))

AfxMessageBox( "建立网络连接出错! ");

//AfxMessageBox( "SendMSG ");

//return;

//AfxMessageBox( "aa ");

::memset(&msg_commanddata,0,sizeof(csock_data));

msg_commanddata.command=pcommand;

msg_commanddata.serial=pmsg;

POINT pt;

GetCursorPos(&pt);

msg_commanddata.mousex=pt.x;

msg_commanddata.mousey=pt.y;

//////////////

char ch[128];

::gethostname(ch,100);

hostent* tent=::gethostbyname(ch);

msg_commanddata.IP[0][0]=(byte)tent-> h_addr[0];

msg_commanddata.IP[0][1]=(byte)tent-> h_addr[1];

msg_commanddata.IP[0][2]=(byte)tent-> h_addr[2];

msg_commanddata.IP[0][3]=(byte)tent-> h_addr[3];

///////////////////////////////////////////

if(!MSG_Socket.Send(msg_commanddata))

{

//

for(int i=0;i <3;i++)

{

//Sleep(100);

if(!MSG_Socket.Send(msg_commanddata))

{

//AfxMessageBox( "send data failed ");

//return;

}

else

{

//AfxMessageBox( "send data failed ");

}

}

}

else

{

}

//AfxMessageBox( "send end ");

//return;

}

[cpp] view
plaincopy

//发送端程序

#include <stdio.h>

#include <winsock.h>

int main(int argc, char* argv[])

{

WSADATA wsaData; //指向WinSocket信息结构的指针

SOCKET sockListener;

SOCKADDR_IN sin,saUdpServ;

BOOL fBroadcast = TRUE;

char sendBuff[1024];

int nSize;

int ncount=0;

// 初始化winsock库,使用socket的前提

if(WSAStartup(MAKEWORD( 1, 1 ), &wsaData )!=0)//进行WinSocket的初始化

{

printf("Can't initiates windows socket!Program stop.\n");//初始化失败返回-1

return -1;

}

// 创建socket

sockListener=socket(PF_INET,SOCK_DGRAM,0);

// 打开广播选项,是socket可以广播消息

setsockopt ( sockListener,SOL_SOCKET,SO_BROADCAST, (CHAR *)&fBroadcast,sizeof ( BOOL ));

// 将socket绑定到本地端口

sin.sin_family = AF_INET;

sin.sin_port = htons(0);

sin.sin_addr.s_addr = htonl(INADDR_ANY);

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

{

printf("Can't bind socket to local port!Program stop.\n");//初始化失败返回-1

return -1;

}

// 设定广播的目的端口

saUdpServ.sin_family = AF_INET;

saUdpServ.sin_addr.s_addr = htonl ( INADDR_BROADCAST );

saUdpServ.sin_port = htons (7001);//发送用的端口,可以根据需要更改

nSize = sizeof ( SOCKADDR_IN );

while(1)

{

// 广播消息

sprintf(sendBuff,"Message %d",ncount++);

sendto ( sockListener,sendBuff,

lstrlen (sendBuff),

0,

(SOCKADDR *) &saUdpServ,

sizeof ( SOCKADDR_IN ));

printf("%s\n",sendBuff);

}

return 0;

}

//接收

#include <stdio.h>

#include <winsock.h>

#include <conio.h>

int main(int argc, char* argv[])

{

WSADATA wsaData; //指向WinSocket信息结构的指针

SOCKET sockListener;

SOCKADDR_IN sin,saClient;

char cRecvBuff[1024];

int nSize,nbSize;

int iAddrLen=sizeof(saClient);

if(WSAStartup(MAKEWORD( 1, 1 ), &wsaData )!=0)//进行WinSocket的初始化

{

printf("Can't initiates windows socket!Program stop.\n");//初始化失败返回-1

return -1;

}

// 绑定到7001端口,以监听来自网络的数据

sockListener=socket(AF_INET, SOCK_DGRAM,0);

sin.sin_family = AF_INET;

sin.sin_port = htons(7001);//发送端使用的发送端口,可以根据需要更改

sin.sin_addr.s_addr = htonl(INADDR_ANY);

if(bind( sockListener, (SOCKADDR FAR *)&sin, sizeof(sin))!=0)

{

printf("Can't bind socket to local port!Program stop.\n");//初始化失败返回-1

return -1;

}

while(1)

{

nSize = sizeof ( SOCKADDR_IN );

// 接受消息

if((nbSize=recvfrom (sockListener,cRecvBuff,1024,0,(SOCKADDR FAR *) &saClient,&nSize))==SOCKET_ERROR)

{

printf("Recive Error");

break;

}

cRecvBuff[nbSize] = '\0';

printf("%s\n",cRecvBuff);

}

return 0;

}

广播

广播是指在一个局域网中向所有的网上节点发送信息。这是UDP连接的一种

广播有一个广播组,即只有一个广播组内的节点才能收到发往这个广播组的信息。什么决定了一个广播组呢,就是端口号,局域网内一个节点,如果设置了广播属性并监听了端口号A后,那么他就加入了A组广播,这个局域网内所有发往广播端口A的信息他都收的到。在广播的实现中,如果一个节点想接受A组广播信息,那么就要先将他绑定给地址和端口A,然后设置这个socket的属性为广播属性。如果一个节点不想接受广播信息,而只想发送广播信息,那么不用绑定端口,只需要先为socket设置广播属性后,向广播地址INADDR_BROADCAST的A端口发送udp信息即可。详细的程序实现如下:

1.初始化

WSAStartup(MAKEWORD(2,2),&wsad);

2.创建一个UDP的socket

s=socket(AF_INET,SOCK_DGRAM,0);

3.如果这个socket希望收到信息,则需要绑定地址和这组广播的端口号,如果只是希望发送广播信息,则不需要这步

SOCKADDR_IN udpAdress,sender;

int senferAddSize=sizeof(sender);

udpAdress.sin_family=AF_INET;

udpAdress.sin_port=htons(11114);

udpAdress.sin_addr.s_addr=inet_addr("10.11.131.32");

bind(s,(SOCKADDR*)&udpAdress,sizeof(udpAdress));

//这样这个节点即可收到局域网内所有发往端口11114的广播信息

4.设置socket的属性为广播

bool optval=true;

setsockopt(s,SOL_SOCKET,SO_BROADCAST,(char*)&optval,sizeof(bool));

5.下面就可以使用recvfrom或sendto来收发广播信息了

这里是接受,这是一个阻塞操作

ret=recvfrom(s,data,1000,0,(SOCKADDR*)&sender,&senferAddSize);

这里是像该广播组发送信息,注意发送的地址为广播地址INADDR_BROADCAST,端口号为改组广播的端口号11114

SOCKADDR_IN dstAdd;

dstAdd.sin_family=AF_INET;

dstAdd.sin_port=htons(11114);

dstAdd.sin_addr.s_addr=INADDR_BROADCAST;

sendto(s,data(),totalbyte,0,(SOCKADDR*)&dstAdd,sizeof(SOCKADDR));

多播

多播与广播不同,多播是指一条信息向局域网内有限几个节点传递,而广播是不管某个节点是否在制定组内,都会向这个节点发送广播信息,容易造成网络负担严重。

多播的实现是靠多播组,在局域网内,一个多播地址唯一的定义了一个多播组(端口号任意),可以使用的多播地址是有规定的,从224.0.0.0—239.255.255.255之间,但是其中的一些地址不能用,是用作特殊用途的:224.0.0.0 –224.0.0.2 224.0.1.1 224.0.0.9 224.0.1.24。一个节点如果想接受自某个多播组或向某个多播组发送信息,必须首先加入多播组,然后给予UDP发送。下面是详细的代码实现。

1.初始化

WSAStartup(MAKEWORD(2,2),&wsad);

2.这里传建一个用于多播通信的socket,注意这个socket的参数为设置成多播

s=WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0,WSA_FLAG_MULTIPOINT_C_LEAF|WSA_FLAG_MULTIPOINT_D_LEAF|WSA_FLAG_OVERLAPPED);

3.将socket绑定到一个本地地址、端口,和广播不同,在多播中,无论是发送还是接收端都必须绑定一个本地地址,这个地址就是多播通信时处理信息的端口

udpAdress.sin_family=AF_INET;

udpAdress.sin_port=htons(22222);

udpAdress.sin_addr.s_addr=inet_addr("10.11.131.32");

bind(s,(SOCKADDR*)&udpAdress,sizeof(udpAdress));

4.定义多播组的地址

multiCastGroup.sin_family=AF_INET;

multiCastGroup.sin_port=htons(1111);此处端口任意,每个节点的可以设置成不同的

multiCastGroup.sin_addr.s_addr=inet_addr("224.0.0.3"); 此处需使用上面规定地址段内的多播地址

5.加入这个多播组。注意这里的函数返回了一个socket,这个socket不负责通信,只是在脱离多播组时使用

SOCKET sockM=WSAJoinLeaf(s,(SOCKADDR*)&multiCastGroup,sizeof(multiCastGroup),NULL,NULL,NULL,NULL,JL_BOTH);

6.下面使用recvfrom接受多播信息,或者使用sendto发送多播信息

ret=recvfrom(s,data,1000,0,(SOCKADDR*)&sender,&senferAddSize);

sendto(s,data(),totalbyte,0,(SOCKADDR*)&multiCastGroup,sizeof(multiCastGroup));

7.最后关闭清理

closesocket(sockM);

closesocket(s);

WSACleanup();

其他:

1)在多播组中,默认情况下一个发出多播信息的节点也会收到自己发送的信息,这称为多播回环,可以关闭多播回环:

bool val=false;

setsocket(s,IPPROTO_IP,IP_MULTICAST_LOOP,(char*)val,sizeof(val));

2)在多播时,通常要设置适当的TTL(TTL的值是多少,那么多播信息就可以经过多少路由器,每经过一个路由器,TTl的值自动减1):

int val=3;

setsocket(s,IPPROTO_IP,IP_MULTICAST_TTL,(char*)val,sizeof(int));

[cpp] view
plaincopy

//////////////////////////////////////////////////////////////////////////

// UDPServer.cpp

#include <stdio.h>

#include <WINSOCK2.H>

#pragma comment(lib,"WS2_32.lib")

#define BUF_SIZE 64

int main(void)

{

WSADATA wsd;

SOCKET s;

int nRet;

// 初始化套接字动态库

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

{

printf("WSAStartup failed !\n");

return 1;

}

// 创建套接字

s = socket(AF_INET,SOCK_DGRAM,0);

if(s == INVALID_SOCKET)

{

printf("socket() failed ,Error Code:%d\n",WSAGetLastError());

WSACleanup();

return 1;

}

SOCKET socketSrv = socket(AF_INET,SOCK_DGRAM,0);

SOCKADDR_IN addrSrv;

SOCKADDR_IN addrClient;

char buf[BUF_SIZE];

int len = sizeof(SOCKADDR);

// 设置服务器地址

ZeroMemory(buf,BUF_SIZE);

addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);

addrSrv.sin_family = AF_INET;

addrSrv.sin_port = htons(5000);

// 绑定套接字

nRet = bind(socketSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

if(SOCKET_ERROR == nRet)

{

printf("bind failed !\n");

closesocket(s);

WSACleanup();

return -1;

}

// 从客户端接收数据

nRet = recvfrom(socketSrv,buf,BUF_SIZE,0,(SOCKADDR*)&addrClient,&len);

if(SOCKET_ERROR == nRet)

{

printf("recvfrom failed !\n");

closesocket(s);

WSACleanup();

return -1;

}

// 打印来自客户端发送来的数据

printf("Recv From Client:%s\n",buf);

// 向客户端发送数据

sendto(socketSrv,"UDP Hello World !",sizeof("UDP Hello World !"),0,(SOCKADDR*)&addrClient,len);

closesocket(s);

WSACleanup();

return 0;

}

[cpp] view
plaincopy

//////////////////////////////////////////////////////////////////////////

// UDPClient.cpp

#include <stdio.h>

#include <WINSOCK2.H>

#pragma comment(lib,"WS2_32.lib")

#define BUF_SIZE 64

int main(void)

{

WSADATA wsd;

SOCKET s;

// 初始化套接字动态库

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

{

printf("WSAStartup failed !\n");

return 1;

}

// 创建套接字

s = socket(AF_INET,SOCK_DGRAM,0);

if(s == INVALID_SOCKET)

{

printf("socket() failed, Error Code:%d\n",WSAGetLastError());

WSACleanup();

return 1;

}

char buf[BUF_SIZE];

// 接受数据

SOCKADDR_IN servAddr;

// 服务器套接字地址

SOCKET sockClient = socket(AF_INET,SOCK_DGRAM,0);

int nRet; ZeroMemory(buf,BUF_SIZE);

strcpy(buf,"UDP Hello World !");

// 设置服务器地址

servAddr.sin_family = AF_INET;

servAddr.sin_addr.S_un.S_addr = inet_addr("192.168.1.254");

servAddr.sin_port = htons(5000);

// 向服务器发送数据

int nServAddLen = sizeof(servAddr);

if(sendto(sockClient,buf,BUF_SIZE,0,(sockaddr *)&servAddr,nServAddLen) == SOCKET_ERROR)

{

printf("recvfrom() failed:%d\n",WSAGetLastError());

closesocket(s);

WSACleanup();

return 1;

}

nRet = recvfrom(sockClient,buf,BUF_SIZE,0,(sockaddr *)&servAddr,&nServAddLen);

if(SOCKET_ERROR == nRet)

{

printf("recvfrom failed !\n");

closesocket(s);

WSACleanup();

return -1;

}

// 打印来自服务端发送来的数据

printf("Recv From Server:%s\n",buf);

closesocket(s);

WSACleanup();

return 0;

}

本文讲述了SOCKADDR 与 SOCKADDR_IN 的区别与联系。已经里面涉及的结构体 联合体 等的一些细节问题。这个是一个很基础的问题,但是很多人都是似是而非的理解着!下面详解了这个谜团!

-----------------------------------------------------------------------------------------------------------------------

struct sockaddr {

unsigned short sa_family; // 地址族, AF_xxx AF_INET 不涉及转序的问题

char sa_data[14]; // 14字节的协议地址 网络字节顺序的

};

上面是通用的socket地址,共16个字节!

具体到Internet socket,用下面的结构,二者可以进行类型转换

struct sockaddr_in {

short int sin_family; /* 地址族 */

unsigned short int sin_port; /* 端口号 */

struct in_addr sin_addr; /* Internet地址 */

unsigned char sin_zero[8]; /* 与struct sockaddr一样的长度 */ 16个字节

};

---------------------------struct in_addr 就是32位IP地址---------------------------------

第一种表示方式:

struct in_addr {

unsigned long s_addr;

};

第二种表示方式:

struct in_addr

{

union

{

struct { u_char s_b1,s_b2,s_b3,s_b4;} S_un_b;

struct { u_short s_w1,s_w2;} S_un_w;

u_long S_addr;

} S_un;

};

利用u_long htonl(u_long hostlong);将主机字节序转换为TCP/IP网络字节序.

利用u_short htons(u_short hostshort);将主机字节序转换为TCP/IP网络字节序.

inet_addr()是将一个点分制的IP地址(如192.168.0.1)转换为上述结构中需要的32位IP地址(0xC0A80001)。

通常的用法是:

SOCKET sockfd;

struct sockaddr_in my_addr; //SOCKETADDR_IN my_addr;

sockfd = socket(AF_INET, SOCK_STREAM, 0); /* 做一些错误检查! */

my_addr.sin_family = AF_INET; /* 主机字节序 */

my_addr.sin_port = htons(MYPORT); /* short, 网络字节序 */

//有两种方式 对应上面 in_addr 的两种方式

my_addr.sin_addr.s_addr = inet_addr("192.168.0.1");

//my_addr.sin_addr.S_un.s_addr = inet_addr("192.168.0.1");

bzero(&(my_addr.sin_zero), 8); /* zero the rest of the struct */

/* 不要忘了为bind()做错误检查: */

bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr));

转自http://blog.csdn.net/jiangxinyu/article/details/7586513
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: