?? server.c
字號:
/*
*TCP Stream Socket Server
*這個例子說明如何實現一個Winsock TCP stream socket服務器。
*它接收從客戶端發過來的消息并且發送一條消息到客戶端。
*/
#include <windows.h>
#include <winsock.h>
#include "resource.h"
#include "PROCESS.H"
#define PORTNUM 5000 // 端口號
#define MAX_PENDING_CONNECTS 4 // 等待連接隊列的最大長度
#define WM_MESSAGE_REVED (WM_USER+0) //接收到數據包消息
#define WM_MESSAGE_SENDED (WM_USER+1) //發送出到數據包消息
//主線程向負責接收和發送的線程傳遞參數
typedef struct
{
HWND hwnd; //主線程的窗口句柄
BOOL bContinue; //狀態指示參數
SOCKET WinSocket; //監聽socket
SOCKADDR_IN local_sin, //本地socket地址
accept_sin; //接收連接的socket地址
}
PARAMS,*PPARAMS;
char szServerA[100]; // ASCII string
TCHAR szServerW[100]; // Unicode string
TCHAR szError[100]; // Error message string
TCHAR szSendBuffer[100]; // 線程間共享緩沖池
SOCKET ClientSock = INVALID_SOCKET; // 服務器和客戶端通信的Socket
BOOL WINAPI MainDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam );
void NetworkThread(PVOID pvoid);
int WINAPI WinMain (
HINSTANCE hInstance, // 實例句柄
HINSTANCE hPrevInstance,// NULL
LPTSTR lpCmdLine, // 用于運行程序的命令行
int nCmdShow) // 程序的最初的顯示方式
{
WNDCLASS wc;
GetClassInfo( NULL, WC_DIALOG, &wc ); // Get dialog box class info
wc.hInstance = hInstance;
wc.lpszClassName = "Client"; // so's we can superclass it
wc.lpfnWndProc = DefDlgProc; // all this for an icon...sheesh
wc.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE( 100 ) );
wc.cbWndExtra = DLGWINDOWEXTRA;
if( ! RegisterClass( &wc ) ) // Quit if registration fails
return( FALSE );
//hInst = hInstance; // Now just start the main dialog and exit
DialogBox( hInstance, MAKEINTRESOURCE(ID_CLIENT), NULL, MainDlgProc );
return TRUE;
}
// === Main Dialog Box ========================================================
BOOL WINAPI MainDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam )
{
static SOCKADDR_IN local_sin, // 本地socket地址
accept_sin; // 接收連接對象的地址
static SOCKADDR_IN destination_sin; // 服務器的socket地址
static PHOSTENT phostent = NULL; // 指向服務器的HOSTENT結構
static WSADATA WSAData; // 包含了Winsocket執行后的細節
static PARAMS params;
static SOCKET WinSocket = INVALID_SOCKET; // Window socket
switch( msg )
{
case WM_INITDIALOG: //初始化對話框消息
{
// 初始化Winsocket.
if (WSAStartup (MAKEWORD(1,1), &WSAData) != 0)
{
wsprintf (szError, TEXT("WSAStartup failed. Error: %d"),
WSAGetLastError ());
MessageBox (NULL, szError, TEXT("Error"), MB_OK);
return FALSE;
}
//創建一個TCP/IP socket, WinSocket.
if ((WinSocket = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
wsprintf (szError, TEXT("Allocating socket failed. Error: %d"),
WSAGetLastError ());
MessageBox (NULL, szError, TEXT("Error"), MB_OK);
return FALSE;
}
// 填寫本地socket地址信息
local_sin.sin_family = AF_INET;
local_sin.sin_port = htons (PORTNUM);
local_sin.sin_addr.s_addr = htonl (INADDR_ANY);
// 把本地地址綁定到WinSocket.
if (bind (WinSocket,
(struct sockaddr *) &local_sin,
sizeof (local_sin)) == SOCKET_ERROR)
{
wsprintf (szError, TEXT("Binding socket failed. Error: %d"),
WSAGetLastError ());
MessageBox (NULL, szError, TEXT("Error"), MB_OK);
closesocket (WinSocket);
return FALSE;
}
// 建立一個socket監聽到來的連接
if (listen (WinSocket, MAX_PENDING_CONNECTS) == SOCKET_ERROR)
{
wsprintf (szError,
TEXT("Listening to the client failed. Error: %d"),
WSAGetLastError ());
MessageBox (NULL, szError, TEXT("Error"), MB_OK);
closesocket (WinSocket);
return FALSE;
}
params.hwnd = hDlg;
params.bContinue = TRUE;
params.WinSocket = WinSocket;
params.accept_sin = accept_sin ;
params.local_sin = local_sin ;
_beginthread(NetworkThread,0,¶ms);
}
case WM_PAINT: // 對話框繪制消息
{
PAINTSTRUCT ps;
HDC hDC;
RECT Rect;
hDC = BeginPaint( hDlg, &ps );
GetClientRect( hDlg, &Rect );
FillRect( hDC, &Rect, GetProp( hDlg, "BRUSH" ) );
EndPaint( hDlg, &ps );
return 0;
}
case WM_MESSAGE_REVED: //輔助線程接收到消息
{
//把接收到的消息在對話框中顯示
SetWindowText( GetDlgItem(hDlg,IDC_EDIT1), szServerW );
return 0;
}
case WM_COMMAND: //處理從控件傳遞來的消息
{
if(wParam == IDC_SEND )
{
//如果用戶點擊發送,從輸入框中取得文本
GetWindowText(GetDlgItem(hDlg,IDC_EDIT),
szSendBuffer,GetWindowTextLength(GetDlgItem(hDlg,IDC_EDIT)));
//發送文本
if (send (ClientSock, szSendBuffer, strlen (szSendBuffer) + 1, 0)
== SOCKET_ERROR)
{
wsprintf (szError,
TEXT("Sending data to the server failed. Error: %d"),
WSAGetLastError ());
MessageBox (NULL, szError, TEXT("Error"), MB_OK);
}
}
else if(wParam == IDCANCEL)
{
EndDialog( hDlg, TRUE );
}
return( TRUE );
}
}
return FALSE;
}
//輔助線程,負責socket通信
void NetworkThread(PVOID pvoid)
{
volatile PPARAMS pparams;
int index = 0, // 索引
iReturn;
int accept_sin_len; // accept_sin的長度
pparams = (PPARAMS)pvoid;
accept_sin_len = sizeof (pparams->accept_sin);
// 接收來自發送到WinSocket的連接請求
ClientSock = accept (pparams->WinSocket,
(struct sockaddr *) &(pparams->accept_sin),
(int *) &accept_sin_len);
// 停止接收客戶端的連接請求
closesocket (pparams->WinSocket);
if (ClientSock == INVALID_SOCKET)
{
wsprintf (szError, TEXT("Accepting connection with client failed.")
TEXT(" Error: %d"), WSAGetLastError ());
MessageBox (NULL, szError, TEXT("Error"), MB_OK);
}
for (;;)
{
// 從客戶端接收數據
iReturn = recv (ClientSock, szServerA, sizeof (szServerA), 0);
// 如果有數據,就顯示之
if (iReturn == SOCKET_ERROR)
{
wsprintf (szError, TEXT("No data is received, recv failed.")
TEXT(" Error: %d"), WSAGetLastError ());
MessageBox (NULL, szError, TEXT("Server"), MB_OK);
break;
}
else if (iReturn == 0)
{
MessageBox (NULL, TEXT("Finished receiving data"), TEXT("Server"),
MB_OK);
break;
}
else
{
// 把ASCII碼字符串轉換成Unicode碼字符串
for (index = 0; index <= sizeof (szServerA); index++)
szServerW[index] = szServerA[index];
// 顯示從服務器接收到的字符串
// MessageBox (NULL, szClientW, TEXT("Received From Server"), MB_OK);
SendMessage(pparams->hwnd,WM_MESSAGE_REVED,0,0);
}
}
// 發送一條消息到客戶端
// 禁止ClientSock的接收和發送端口.
shutdown (ClientSock, 0x02);
// 關閉ClientSock.
closesocket (ClientSock);
WSACleanup ();
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -