用Socket在區域網內進行廣播
伺服器和客戶機採用Socket程式設計。
問題1:伺服器進入偵聽狀態,但是此時客戶端並不知道伺服器的地址。我該如何做?
問題2:我想使客戶端先發出一個廣播,伺服器接受廣播後給客戶機發送自己的Ip等資訊。
接著再建立Socket通訊。這樣對嗎?
問題3:是不是進行廣播必須是資料報SOCK_DGRAM
問題4:是不是通訊的雙方必須都是資料流或資料報?如果伺服器是資料流SOCK_STREAM套接字,而客戶機是資料報套接字就不能夠通訊?
1、用廣播(或組播)方式,客戶端不需道伺服器的地址,初始化時用程式建立一個新的廣播地址。
2、用廣播(或組播)方式,可直接收發資料。不用偵聽。
3、是;
4、只要是資料就行。
例子:
// 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; } }
#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; }
//傳送端程式
#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));
//////////////////////////////////////////////////////////////////////////
// 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;
}
//////////////////////////////////////////////////////////////////////////
// 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));
相關推薦
用Socket在區域網內進行廣播
伺服器和客戶機採用Socket程式設計。 問題1:伺服器進入偵聽狀態,但是此時客戶端並不知道伺服器的地址。我該如何做? 問題2:我想使客戶端先發出一個廣播,伺服器接受廣播後給客戶機發送自己的Ip等資訊。 接著再建立Socket通訊。這樣對嗎? 問題3:是不是進行廣播
Linux、window伺服器下建立共享資料夾(方便與區域網內進行檔案共享)
SEO關鍵字:samba伺服器的搭建 ServU的安裝使用 玉念聿輝 Linux共享檔案 window共享檔案 深圳市奧捷迅科技 吳明輝 感謝CSDN品臺。 Linux下samba的安裝和建立共享檔案 1、關閉selinux setenforce 0 2、關閉ipta
不同區域網內進行網路連線的建立方法
前言 在這網際網路和物聯網的時代,網路連線與通訊被使用的越來越多,如何建立兩個網路IP地址的連線 (TCP或者UDP連線),也是一門學問。之前專案中遇到了這方面的問題,也被糾纏了一番,查閱大量資料,通過不斷摸索和學習,對網路通訊有了一定的理解,下面以個人的理解
python 獲取區域網內的廣播地址
#-*- coding:utf-8 -*- import subprocess import re import socket def getBroadAddList(): ######獲取IP以及子網掩碼 #######windows 下的命令是ipcon
Python Socket網路程式設計(二)區域網內和區域網與廣域網的持續通訊
目錄 前言 IP地址 簡介 公有IP 私有IP 區域網之間網路通訊 前提 功能描述
python用tcp實現區域網內檔案傳輸(文字,圖片,視訊)
功能: 可以利用python建立的TCP客戶端從我們自己搭建的TCP伺服器上下載檔案. 實現需求: 安裝socket模組 簡單瞭解sokcet模組用法 伺服器程式碼如下: import socket def file_deal(file_name): # 定義
如何把區域網內不同資料庫的兩個表的資料進行傳輸?
應用場景:當測試資料庫的資料不小心被清空了,需要從別的庫裡把資料恢復過來;或者測試庫增加了某表的一些資料,正式庫需要同時更新(當然穩妥的是儲存更新語句)等等,這時就需要用到這個小技巧了。 第一句是把b表中的選單表的資料放到當前資料庫中,並且新建一張tmenu表: select * into TMENU f
ZeroMQ例項-使用ZMQ(ZeroMQ)進行區域網內網路通訊
本文內容摘要:1)安裝zeromq、2)例項說明使用zmq進行網路間的訊息傳送和接收 首先在機器中安裝zmq庫 步驟如下: 1)下載zeromq的原始碼,ZeroMQ的官方網址: 注:在本文寫作時,ZMQ版本已經升級到4.1.0,不過影響沒多大 2)解壓原始檔 tar
區域網內主機之間Socket通訊實現
只能傳輸文字且只能在區域網內實現通訊 主機1: package SocketTest; import java.net.*; import java.io.*; import java.awt.*; import javax.swing.*; import java.u
【C#】-區域網下用Socket實現通訊
前言 聽起區域網下聊天是不是很難,很高大上的樣子,怎麼樣讓兩臺電腦,在同一區域網下實現聊天呢,先說一下思路吧,一會直接上程式碼。 1. 首先我們先要建立一個伺服器,也就是說兩臺電腦有一臺要當著伺服器,供客戶端連結。 2.
用Socket做一個區域網聊天工具
程式設計成為簡單的服務端和客戶端之間的通訊, 但通過一些方法可以將這兩者進行統一起來, 讓服務端也成為客戶端, 讓客戶端也成為服務端, 使它們之間可以互相隨時不間斷的通訊. 考慮到實現最原始的服務端和客戶端之間的通訊所需要的步驟對於寫這樣的程式是很有幫助的. 作為服務端,
使用arp欺騙進行同一區域網內的抓包
環境 作業系統: MacOS 10.13.4 包管理工具:MacPorts 2.4.4 arp欺騙工具:arpspoof 2.4 抓取區域網內的IP地址的工具:nmap 7.70 抓包工具:Wireshark 2.4.3 前言 本來是想了解如何
用Socket實現服務端和客戶端,進行一對一順序對話
一、服務端程式碼 import java.net.ServerSocket; import java.net.Socket; import java.io.IOException; import java.io.InputStream; import ja
【技巧】用手機訪問區域網內Apache網站
寫在前面 之前不知道還有這麼一個技巧,以前手機真機測試webApp都是開電腦的WiFi,然後在手機裡開啟代理來訪問這個網站。這樣對裝置的依賴性比較大,試想哪天沒帶膝上型電腦,或者在沒有WiFi發射器的桌上型電腦裡怎麼用這個方式? Apache配置修改
區域網內用IIS架設網站,解決本機可訪問,但網內其他使用者無法訪問問題
在Window7作業系統中安裝配置好IIS後,本地釋出測試網站程式沒有問題,但是區域網等遠端使用者不能正常訪問網站程式,提示“Internet Explorer 無法顯示該網頁”。本地可以正常訪問IIS但是遠端不能訪問
有1000瓶藥水,其中只有一瓶有毒。現在用小白鼠進行實驗,小白鼠只要服用任意量有毒藥水就會在24小時內死亡。問至少要用多少隻小白鼠進行實驗才能檢測出哪瓶藥水有毒?
時間不是問題,24小時內肯定可以找出有毒的那瓶。 給1000個瓶分別標上如下標籤(10位長度): 0000000001 (第1瓶) 0000000010 (第2瓶) 0000000011 (第3瓶) ...... 1111101000 (第1000瓶) 從編號
【MySQL比知必會】第八章 用通配符進行過濾
通配符 操作符 範圍 name 使用 技巧 商品 -- rom 1、LIKE操作符 之前使用的操作符都是針對已知的數據,而使用通配符可以對未知數據也進行搜索。 通配符(wildcard):用來匹配值得一部分的特殊字符。 搜索模式(search pattern):
字符設備驅動ioctl實現用戶層內核層通信
default eof 建設 code gcc app std size smo 測試代碼實現 memdev.h #ifndef _MEMDEV_H_ #define _MEMDEV_H_ #include<linux/ioctl.h> #ifndef MEM
用XMLRPC開服務進行server/client通信
elif 工具 註意事項 tar ann popu cannot family put 本文講一下怎樣用python的xmlrpc開服務,進行server/client的通信。應用場景:1)需多client訪問應用程序給予應答情況——網頁服務。 2)數據極大,希望載入一
使用python3.x實現統計Nginx進程所占用的物理內存
linux 進程 統計 python nginx 實現代碼如下:#!/usr/bin/python #coding:utf8 from subprocess import Popen, PIPE import os nginxpid = Popen(["pidof", "nginx"]