以前在linux上面写过socket的通信,今天想在windows下面再用SDK重新写一遍
下面先附张图片来看看整个框架:
然后自己先在控制台下实现:
服务器端:
#include <stdio.h> #include <WinSock2.h> #pragma comment (lib, "ws2_32.lib") #define MAXLINE 4096 int main() { WSADATA wsaData; SOCKET ListeningSocket; SOCKET NewConnection; SOCKADDR_IN ServerAddr; SOCKADDR_IN ClientAddr; int Port = 10000; int ClientAddrLen; int iResult; int n; char buff[MAXLINE]; char sendline[MAXLINE]; int send_bytes; //初始化Windows Socket 2.2 WSAStartup(MAKEWORD(2, 2), &wsaData ); //创建socket ListeningSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //填写服务端地址信息 //端口为10000 //IP地址 ServerAddr.sin_family = AF_INET; ServerAddr.sin_port = htons(Port); ServerAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); //绑定监听端口 iResult = bind(ListeningSocket, (SOCKADDR*) &ServerAddr, sizeof(ServerAddr)); if (iResult == SOCKET_ERROR) { printf("bind faied: %d\n", WSAGetLastError()); } else { printf("bind succeed!\n"); } //监听 iResult = listen(ListeningSocket, 10); if (iResult == SOCKET_ERROR) { printf("listen failed %d\n", WSAGetLastError()); } else { printf("listen succeed!\n"); } //接受建立连接 printf("wait for linking........\n"); while (1) { //NewConnection = accept(ListeningSocket, (SOCKADDR*)&ClientAddr, &ClientAddrLen); NewConnection = accept(ListeningSocket, NULL, NULL); memset(buff, 0, MAXLINE); if (NewConnection == INVALID_SOCKET) { //printf("accept socket error!\n"); printf("accept failed %d\n", WSAGetLastError()); continue; } else { while(1) { //服务器端接受消息 n = recv(NewConnection, buff, MAXLINE, 0); if (n == -1) break; else { buff[n] = 0; printf("从客户端来的消息:%s\n", buff); //closesocket(NewConnection); //continue; } //服务器端发送消息 memset(sendline, 0, MAXLINE); printf("请输入发送消息\n"); gets(sendline); send_bytes = send(NewConnection, sendline, strlen(sendline), 0); if (send_bytes > 0) { printf("发送消息成功,发送消息字节数为%d\n", send_bytes); } else { printf("发送消息失败,发送消息字节数为%d\n", send_bytes); } } } } //关闭监听Socket closesocket(NewConnection); closesocket(ListeningSocket); //释放windows socket DLL的相关资源 WSACleanup(); return 0; }
客户端:
#include <stdio.h> #include <WinSock2.h> #pragma comment (lib, "ws2_32.lib") #define MAXLINE 4096 int main() { WSADATA wsaData;//库文件 SOCKET s;//socket SOCKADDR_IN ServerAddr; int Port = 10000; int send_bytes; int n; char buff[MAXLINE]; char sendline[MAXLINE]; //初始化Windows Socket 2.2 WSAStartup(MAKEWORD(2, 2), &wsaData ); //创建socket s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //填写服务端地址信息 //端口为10000 //IP地址 ServerAddr.sin_family = AF_INET; ServerAddr.sin_port = htons(Port); ServerAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); //绑定监听端口 因为是客户端,这里我们就不需要绑定了 //bind(ListeningSocket, (SOCKADDR*) &ServerAddr, sizeof(ServerAddr)); //接受新的连接 服务器端才接受连接 //NewConnection = accept(ListeningSocket, (SOCKADDR*)&ClientAddr, &ClientAddrLen); //这里是客户端, 所以应该请求连接 if (connect(s, (SOCKADDR*) &ServerAddr, sizeof(ServerAddr)) != 0) { printf("连接错误!\n"); } else { printf("连接成功!\n"); while(1) { //客户端发送消息 memset(sendline, 0, MAXLINE); printf("请输入发送消息\n"); gets(sendline); send_bytes = send(s, sendline, strlen(sendline), 0); if (send_bytes > 0) { printf("发送消息成功,发送消息字节数为%d\n", send_bytes); } else { printf("发送消息失败,发送消息字节数为%d\n", send_bytes); } //客户端接受消息 n = recv(s, buff, MAXLINE, 0); if (n == -1) break; else { buff[n] = 0; printf("从客户端来的消息:%s\n", buff); //closesocket(NewConnection); //continue; } } } //关闭监听Socket closesocket(s); //释放windows socket DLL的相关资源 WSACleanup(); return 0; }
然后在控制台实现的基础上,尝试用SDK写一下,加上了点自己的创意,做个帮室友找对象的小软件。
客户端用到了对话框和菜单资源,服务器端没有用资源,直接用的窗口子类化写的。
client
#include <windows.h> #include "resource.h" #include <stdio.h> #pragma comment (lib, "ws2_32.lib") #define MAXLINE 4096 LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; BOOL CALLBACK AboutDlgProc (HWND, UINT, WPARAM, LPARAM) ; BOOL CALLBACK ServerDlgProc (HWND, UINT, WPARAM, LPARAM) ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT ("ModeDia") ; HWND hwnd ; MSG msg ; WNDCLASS wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = szAppName ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { MessageBox (NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow (szAppName, TEXT ("帮室友找对象"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc ; PAINTSTRUCT ps ; RECT rect ; static HINSTANCE hInstance; switch (message) { case WM_CREATE: hInstance = ((LPCREATESTRUCT) lParam) -> hInstance; return 0 ; case WM_COMMAND: switch (LOWORD (wParam)) { case IDM_APP_ABOUT : DialogBox (hInstance, TEXT("AboutBox"), hwnd, AboutDlgProc); break; case IDM_APP_SERVER : DialogBox(hInstance, TEXT("ServerInfo"),hwnd,ServerDlgProc); } return 0; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; GetClientRect (hwnd, &rect) ; DrawText (hdc, TEXT ("还在搞基?你OUT了!帮室友找对象,去寻找你心中的她把!!"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER) ; EndPaint (hwnd, &ps) ; return 0 ; case WM_DESTROY: PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; } BOOL CALLBACK AboutDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: //这里我们来处理socket { WSADATA wsaData;//库文件 SOCKET s;//socket SOCKADDR_IN ServerAddr; char buff1[MAXLINE]; char buff2[MAXLINE]; char buff3[MAXLINE]; int n; int Port = 10000; int send_bytes; TCHAR sendline[MAXLINE]; //初始化Windows Socket 2.2 WSAStartup(MAKEWORD(2, 2), &wsaData ); //创建socket s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //填写服务端地址信息 //端口为10000 //IP地址 ServerAddr.sin_family = AF_INET; ServerAddr.sin_port = htons(Port); ServerAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); if (connect(s, (SOCKADDR*) &ServerAddr, sizeof(ServerAddr)) != 0) { MessageBox(hDlg, TEXT("连接错误"), TEXT("错误啦"), MB_OK); } else { MessageBox(hDlg, TEXT("连接成功"), TEXT("成功啦"), MB_OK); while(1) { //客户端发送消息 memset(sendline, 0, MAXLINE); GetDlgItemText(hDlg, IDC_NAME, sendline, sizeof(sendline)); send_bytes = send(s, (const char*)sendline, sizeof(sendline)/sizeof(TCHAR), 0); memset(sendline, 0, MAXLINE); GetDlgItemText(hDlg, IDC_AGE, sendline, sizeof(sendline)); send_bytes = send(s, (const char*)sendline, sizeof(sendline)/sizeof(TCHAR), 0); memset(sendline, 0, MAXLINE); GetDlgItemText(hDlg, IDC_INFO, sendline, sizeof(sendline)); send_bytes = send(s, (const char*)sendline, sizeof(sendline)/sizeof(TCHAR), 0); //客户端接收消息 memset(buff1, 0, MAXLINE); memset(buff2, 0, MAXLINE); memset(buff3, 0, MAXLINE); n = recv(s, buff1, MAXLINE, 0); n = recv(s, buff2, MAXLINE, 0); n = recv(s, buff3, MAXLINE, 0); SetDlgItemText(hDlg, IDC_NAME1, (LPCWSTR)buff1); SetDlgItemText(hDlg, IDC_AGE1, (LPCWSTR)buff2); SetDlgItemText(hDlg, IDC_INFO1, (LPCWSTR)buff3); if (send_bytes > 0) { MessageBox(hDlg, TEXT("发送消息成功"), TEXT("成功啦"), MB_OK); break; } else { MessageBox(hDlg, TEXT("发送消息失败"), TEXT("失败啦"), MB_OK); break; } } } //关闭监听Socket closesocket(s); //释放windows socket DLL的相关资源 WSACleanup(); return 0; } case IDCANCEL: EndDialog(hDlg, 0); return TRUE; } break; } return FALSE; } BOOL CALLBACK ServerDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: EndDialog(hDlg, 0); return TRUE; } break; } return FALSE; }
server
/*------------------------------------------------------------ TCP 通信之帮室友找对象 服务器端 Powered by Miibotree ------------------------------------------------------------*/ #include <windows.h> #include <stdio.h> #pragma comment (lib, "ws2_32.lib") #define MAXLINE 4096 #define IDC_BUTTON1 1001 #define IDC_BUTTON2 1002 #define IDC_EDIT1 1003 #define IDC_EDIT2 1004 #define IDC_EDIT3 1005 #define IDC_EDIT4 1006 #define IDC_EDIT5 1007 #define IDC_EDIT6 1008 LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); //int Listen_socket(HWND hwnd, int choose); int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT("server"); HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { MessageBox (NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow (szAppName, TEXT ("这里是天堂社区,负责牵红线射丘比特之箭"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, iCmdShow); UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; RECT rect; HWND hwndButton; HWND hwndEdit; static int cxChar, cyChar; switch(message) { case WM_CREATE: cxChar = LOWORD (GetDialogBaseUnits ()) ; cyChar = HIWORD (GetDialogBaseUnits ()) ; hwndButton = CreateWindow ( TEXT("button"), TEXT("月老/丘比特开始连线"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, cxChar + 420, cyChar * (1 + 2 * 1)+350, 20 * cxChar, 7 * cyChar / 4, hwnd, (HMENU) IDC_BUTTON1, ((LPCREATESTRUCT) lParam)->hInstance, NULL) ; hwndEdit = CreateWindow (TEXT("edit"),NULL, WS_CHILD | WS_VISIBLE | WS_BORDER|ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL, cxChar+200 , cyChar * (1 + 2 * 1)+40, 20 * cxChar, (7 * cyChar / 4)*2, hwnd, (HMENU)IDC_EDIT1, ((LPCREATESTRUCT) lParam)->hInstance, NULL) ; hwndEdit = CreateWindow (TEXT("edit"),NULL, WS_CHILD | WS_VISIBLE | WS_BORDER|ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL, cxChar+200 , cyChar * (1 + 2 * 1)+140, 20 * cxChar, (7 * cyChar / 4)*2, hwnd, (HMENU)IDC_EDIT2, ((LPCREATESTRUCT) lParam)->hInstance, NULL) ; hwndEdit = CreateWindow (TEXT("edit"),NULL, WS_CHILD | WS_VISIBLE | WS_BORDER|ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL, cxChar+200 , cyChar * (1 + 2 * 1)+240, 20 * cxChar, (7 * cyChar / 4)*2, hwnd, (HMENU)IDC_EDIT3, ((LPCREATESTRUCT) lParam)->hInstance, NULL) ; hwndEdit = CreateWindow (TEXT("edit"),NULL, WS_CHILD | WS_VISIBLE | WS_BORDER|ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL, cxChar+700 , cyChar * (1 + 2 * 1)+40, 20 * cxChar, (7 * cyChar / 4)*2, hwnd, (HMENU)IDC_EDIT4, ((LPCREATESTRUCT) lParam)->hInstance, NULL) ; hwndEdit = CreateWindow (TEXT("edit"),NULL, WS_CHILD | WS_VISIBLE | WS_BORDER|ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL, cxChar+700 , cyChar * (1 + 2 * 1)+140, 20 * cxChar, (7 * cyChar / 4)*2, hwnd, (HMENU)IDC_EDIT5, ((LPCREATESTRUCT) lParam)->hInstance, NULL) ; hwndEdit = CreateWindow (TEXT("edit"),NULL, WS_CHILD | WS_VISIBLE | WS_BORDER|ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL, cxChar+700 , cyChar * (1 + 2 * 1)+240, 20 * cxChar, (7 * cyChar / 4)*2, hwnd, (HMENU)IDC_EDIT6, ((LPCREATESTRUCT) lParam)->hInstance, NULL) ; return 0; case WM_PAINT: //GetClientRect(hwnd, &rect); //DrawText(hdc, TEXT("我是万能的牵红线的死老头,我是万能的乱射箭的丘比特"), -1, &rect, // DT_SINGLELINE | DT_CENTER | DT_VCENTER); LOGFONT a; a.lfHeight=25; a.lfWidth=10; a.lfEscapement=0; a.lfWeight=700; a.lfItalic=FALSE; a.lfUnderline=FALSE; a.lfStrikeOut=FALSE; a.lfCharSet =GB2312_CHARSET; hdc = BeginPaint (hwnd, &ps); GetClientRect (hwnd, &rect); SelectObject(hdc,CreateFontIndirect(&a)); SetTextColor(hdc,(100,200,50)); TextOut(hdc, 100, 30, L"征婚启事", wcslen(L"征婚启事")); TextOut(hdc, 100, 100, L"姓名", wcslen(L"姓名")); TextOut(hdc, 100, 200, L"年龄", wcslen(L"年龄")); TextOut(hdc, 100, 300, L"信息", wcslen(L"信息") ); TextOut(hdc, 600, 30, L"应婚启事", wcslen(L"应婚启事")); TextOut(hdc, 600, 100, L"姓名", wcslen(L"姓名")); TextOut(hdc, 600, 200, L"年龄", wcslen(L"年龄")); TextOut(hdc, 600, 300, L"信息", wcslen(L"信息") ); TextOut(hdc, 800, 450, L"MiiBotree制作", wcslen(L"MiiBotree制作") ); EndPaint(hwnd, &ps); return 0; case WM_COMMAND: switch(LOWORD(wParam)) case IDC_BUTTON1: { WSADATA wsaData; SOCKET ListeningSocket; SOCKET NewConnection; SOCKADDR_IN ServerAddr; SOCKADDR_IN ClientAddr; int Port = 10000; int ClientAddrLen; int iResult; int n; char buff1[MAXLINE]; char buff2[MAXLINE]; char buff3[MAXLINE]; int send_bytes; TCHAR sendline[MAXLINE]; //初始化Windows Socket 2.2 WSAStartup(MAKEWORD(2, 2), &wsaData ); //创建socket ListeningSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //填写服务端地址信息 //端口为10000 //IP地址 ServerAddr.sin_family = AF_INET; ServerAddr.sin_port = htons(Port); ServerAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); //绑定监听端口 iResult = bind(ListeningSocket, (SOCKADDR*) &ServerAddr, sizeof(ServerAddr)); if (iResult == SOCKET_ERROR) { MessageBox(hwnd, TEXT("bind faild"), TEXT("wrong"), MB_OK); //printf("bind faied: %d\n", WSAGetLastError()); } else { MessageBox(hwnd, TEXT("bind success"), TEXT("success"), MB_OK); } //监听 iResult = listen(ListeningSocket, 10); if (iResult == SOCKET_ERROR) { MessageBox(hwnd, TEXT("listen faild"), TEXT("wrong"), MB_OK); } else { MessageBox(hwnd, TEXT("listen success"), TEXT("success"), MB_OK); } //接受建立连接 while (1) { NewConnection = accept(ListeningSocket, NULL, NULL); if (NewConnection == INVALID_SOCKET) { MessageBox(hwnd, TEXT("accept faild"), TEXT("wrong"), MB_OK); continue; } else { memset(buff1, 0, MAXLINE); memset(buff2, 0, MAXLINE); memset(buff3, 0, MAXLINE); n = recv(NewConnection, buff1, MAXLINE, 0); n = recv(NewConnection, buff2, MAXLINE, 0); n = recv(NewConnection, buff3, MAXLINE, 0); if (n == -1) break; else { SetDlgItemText(hwnd, IDC_EDIT1, (LPCWSTR)buff1); SetDlgItemText(hwnd, IDC_EDIT2, (LPCWSTR)buff2); SetDlgItemText(hwnd, IDC_EDIT3, (LPCWSTR)buff3); //closesocket(NewConnection); } memset(sendline, 0, MAXLINE); GetDlgItemText(hwnd, IDC_EDIT4, sendline, sizeof(sendline)); send_bytes = send(NewConnection, (const char*)sendline, sizeof(sendline)/sizeof(TCHAR), 0); memset(sendline, 0, MAXLINE); GetDlgItemText(hwnd, IDC_EDIT5, sendline, sizeof(sendline)); send_bytes = send(NewConnection, (const char*)sendline, sizeof(sendline)/sizeof(TCHAR), 0); memset(sendline, 0, MAXLINE); GetDlgItemText(hwnd, IDC_EDIT6, sendline, sizeof(sendline)); send_bytes = send(NewConnection, (const char*)sendline, sizeof(sendline)/sizeof(TCHAR), 0); break; } } //关闭监听Socket closesocket(NewConnection); closesocket(ListeningSocket); //释放windows socket DLL的相关资源 WSACleanup(); } return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); }