監聽線程函數:
DWord WINAPI CServerDlg::ListenThread(LPVOID lpparam)
{
CServerDlg* pDlg = (CServerDlg*)lpparam;
if(pDlg == NULL)
return 0;
SOCKET Listening = pDlg->m_Listening;
//開始監聽是否有客戶端連接。
if(listen(Listening,40) == SOCKET_ERROR)
{
return 0;
}
char szBuf[MAX_PATH];
//初始化
memset(szBuf,0,MAX_PATH);
while(1)
{
SOCKET ConnectSocket;
sockaddr_in ClIEntAddr;
int nLen = sizeof(sockaddr);
//阻塞直到有客戶端連接,不然多浪費CPU資源。
ConnectSocket = accept(Listening,(sockaddr*)&ClIEntAddr,&nLen);
//都到客戶端的IP地址。
char *pAddrname = inet_ntoa(ClIEntAddr.sin_addr);
pDlg->Receive(ConnectSocket,szBuf,100);
//界面上顯示請求數據。
pDlg->SetRequestText(szBuf);
strcat(szBuf," :我是老貓,收到(");
strcat(szBuf,pAddrname);
strcat(szBuf,")");
//向客戶端發送回應數據
pDlg->Send(ConnectSocket,szBuf,100);
}
return 0;
}
服務器端一直在監聽是否有客戶端連接,如有連接,處理客戶端的請求,給出回應,然後繼續監聽。
客戶端:
客戶端的發送函數:
#define DEFAULT_PORT 2000
void CClIEntDlg::OnSend()
{
DWord dwIP = 0;
TCHAR szText[MAX_PATH];
memset(szText,0,MAX_PATH);
m_IP.GetWindowText(szText,MAX_PATH);
//把字符串形式的IP地址轉成IN_ADDR結構需要的形式。
dwIP = inet_addr(szText);
m_RequestEdit.GetWindowText(szText,MAX_PATH);
sockaddr_in local;
SOCKET socketTmp;
//必須是AF_INET,表示該socket在Internet域中進行通信
local.sin_family=AF_INET;
//端口號
local.sin_port=htons(DEFAULT_PORT);
//服務器的IP地址。
local.sin_addr.S_un.S_addr=dwIP;
////初始化Socket
socketTmp=socket(AF_INET,SOCK_STREAM,0);
//連接服務器
if(connect(socketTmp,(LPSOCKADDR)&local,sizeof(local)) < 0)
{
closesocket(socketTmp);
MessageBox("連接服務器失敗。");
return ;
}
//發送請求,為簡單只發100字節,在服務器端也規定100字節。
Send(socketTmp,szText,100);
//讀取服務器端返回的數據。
memset(szText,0,MAX_PATH);
//接收服務器端的回應。
Receive(socketTmp,szText,100);
TCHAR szMessage[MAX_PATH];
memset(szMessage,0,MAX_PATH);
strcat(szMessage,szText);
//界面上顯示回應數據。
m_ReplyBtn.SetWindowText(szMessage);
closesocket(socketTmp);
}
客戶端就一個函數完成了一次通信。在這裡IP地址為何用127.0.0.1呢?使用這個IP地址,服務器端和客戶端就能運行在同一台機器上,這樣調試方便多了。當然你可以在你朋友的機器上運行Server程序(本人在局域網中測試過),在自己的機器上運行ClIEnt程序,當然輸入的IP地址就該是你朋友機器的IP地址了。
簡單的理論和實踐都說了,現在Socket編程不神秘了吧?希望對你有些幫助。