以前在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);
}
最后发个效果图: