socket用法
套接字是很常用的网络编程用法,我将以一个简单的例子来说明它,也就是程序间的通信。
程序说明
主要是一个检测控制系统,一个用来检测环境,一个用来改变环境,这二者可以算作是服务器,另一个客户端就是现实环境了
检测端核心代码
void Process(SOCKET sockLocal, SOCKET sockShow, SOCKET sockControl, HWND hDlg)
{
SOCKET sockEnvironment;
socklen_t len = sizeof(SOCKADDR);
char buffer[1000];
bool transport = false;
connect(sockShow, (SOCKADDR*)&addrShow, len);
while (execute)
{
Sleep(100);
//连接控制器,显示器
connect(sockControl, (SOCKADDR*)&addrControl, len);
sockEnvironment = accept(sockLocal, (SOCKADDR*)&addrEnvironment, &len);
if (sockEnvironment == INVALID_SOCKET)
continue;
else
{
int res = recv(sockEnvironment, buffer, sizeof(buffer), 0);
if (res != SOCKET_ERROR && res != 0)
{
memcpy(&env, buffer, sizeof(env));
if (!(env.dian131 >= 1 && env.dian131 <= 5 && env.tan14 >= 3 && env.tan14 <= 5 && env.chuan >= 40 && env.chuan <= 50 && env.se134 >= 20 && env.se134 <= 50 && env.se137 >= 18 && env.se137 <= 25 && env.gu60 >= 98 && env.gu60 <= 110))
{
wsprintf(tempBuf, L"%s:", strTime);
SendDlgItemMessage(hDlg, IDC_LIST2, LB_ADDSTRING, 0, (LPARAM)tempBuf);
delete[] tempBuf;
tempBuf = new TCHAR[MAX_LENGTH];
/*加入判断检测*/
}
memcpy(buffer, &env, sizeof(env));
send(sockControl, buffer, sizeof(env), 0);
send(sockShow, buffer, sizeof(env), 0);
}
}
}
}
int state = WSAStartup(MAKEWORD(2, 2), &wsadata);
if (state)
{
MessageBox(NULL, L"警告", L"Socket初始化失败!", MB_OK | MB_ICONWARNING);
closesocket(sockLocal);
closesocket(sockShow);
WSACleanup();
DefWindowProc(hwnd, msg, wparam, lparam);
PostQuitMessage(-1);
return -1;
}
//配置socket
sockLocal = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
addrLocal.sin_addr.S_un.S_addr = inet_addr(IpAddr); //ip地址
addrLocal.sin_family = AF_INET;
addrLocal.sin_port = htons(ServerPort1); //设定端口
ioctlsocket(sockLocal, FIONBIO, &mode);
_WINSOCK2API_::bind(sockLocal, (SOCKADDR*)&addrLocal, sizeof(SOCKADDR));
listen(sockLocal, 5);
addrShow.sin_addr.S_un.S_addr = inet_addr(Ip2Addr); //ip地址
addrShow.sin_family = AF_INET;
addrShow.sin_port = htons(ServerPort2); //设定端口
sockShow = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
ioctlsocket(sockShow, FIONBIO, &mode);
addrControl.sin_addr.S_un.S_addr = inet_addr(Ip3Addr); //ip地址
addrControl.sin_family = AF_INET;
addrControl.sin_port = htons(ServerPort3); //设定端口
sockControl = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
ioctlsocket(sockControl, FIONBIO, &mode);
addrEnvironment.sin_addr.S_un.S_addr = inet_addr(Ip4Addr); //ip地址
addrEnvironment.sin_family = AF_INET;
addrEnvironment.sin_port = htons(ServerPort4); //设定端口
swprintf_s(temp_buf, L"检测已开始!");
SendMessage(ListBox, LB_ADDSTRING, 0, (LPARAM)temp_buf);
EnableWindow(GetDlgItem(hwnd, IDSTART), FALSE);
EnableWindow(GetDlgItem(hwnd, IDCLOSE), TRUE);
execute = true;
exe = thread(Process, sockLocal, sockShow, sockControl, hwnd);
exe.detach();
}break;
case IDCLOSE:
{
EnableWindow(GetDlgItem(hwnd, IDCLOSE), FALSE);
closesocket(sockLocal);
closesocket(sockShow);
closesocket(sockControl);
SendDlgItemMessage(hwnd, IDC_LIST2, LB_ADDSTRING, 0, (LPARAM)L"检测已停止!");
execute = false;
//transport = false;
EnableWindow(GetDlgItem(hwnd, IDSTART), TRUE);
}break;
case IDD_SET:
DialogBox(hInstance, MAKEINTRESOURCE(IDD_SETTING), hwnd, Settings);
break;
case IDD_ABOUT:
DialogBox(hInstance, MAKEINTRESOURCE(IDD_ABOUT), hwnd, About);
default:
break;
主要的就是这些,其它的主要就是窗体的配置,这里就不解释了。
控制端
控制端就是用来接收检测端信息的,并对环境进行更改,核心代码如下:
BOOL CALLBACK Setting(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
wchar_t tempBuf[20];
static DWORD ip;
switch (message)
{
case WM_INITDIALOG:
swprintf_s(tempBuf, L"%s", cport);
SendMessage(GetDlgItem(hWnd, IDC_EDIT1), WM_SETTEXT, sizeof(tempBuf), (LPARAM)tempBuf);
ip = inet_addr(cip);
SendMessage(GetDlgItem(hWnd, IDC_IPADDRESS1), IPM_SETADDRESS,0 , (LPARAM)ntohl(ip));
swprintf_s(tempBuf, L"%s", lport);
SendMessage(GetDlgItem(hWnd, IDC_EDIT3), WM_SETTEXT, sizeof(tempBuf), (LPARAM)tempBuf);
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
SendMessage(GetDlgItem(hWnd, IDC_EDIT1), WM_GETTEXT, sizeof(cport), (LPARAM)cport);//获取发送端口
SendMessage(GetDlgItem(hWnd, IDC_IPADDRESS1 ), IPM_GETADDRESS, 0, (LPARAM)&ip);
sprintf_s(cip, "%d.%d.%d.%d", FIRST_IPADDRESS(ip), SECOND_IPADDRESS(ip),
THIRD_IPADDRESS(ip), FOURTH_IPADDRESS(ip));
SendMessage(GetDlgItem(hWnd, IDC_EDIT3), WM_GETTEXT, sizeof(lport), (LPARAM)lport);//获取发送端口
EndDialog(hWnd, 0);
return TRUE;
case IDCANCEL:
EndDialog(hWnd, 0);
return TRUE;
}
return TRUE;
}
return FALSE;
}
int JudgeScope() {
/*判断,并统计错误数据*/
}
void AdjustScope(int i, HWND hShow) {
/*判断数据,之后发送*/
SendMessage(hShow, LB_ADDSTRING, 0, (LPARAM)temp);
}
本质上其实就是两个进程的通信,不过是使用socket的通信,只需不停send recieve就可以交换信息了,也就可以执行了。