草庐IT

VS 2019 MFC Socket 通讯例程客户端Connect连接一对多同步通信TCP/IP通信客户端[二]

lzc881012 2023-11-26 原文

 技术要点:

SOCKET socket(  int af,  int type,  int protocol);
int connect( SOCKET s, const struct sockaddr FAR* name, int namelen);BOOL AfxSocketInit(WSADATA* lpwsaData = NULL );
Visual C++ 
if (!AfxSocketInit())
{
   AfxMessageBox(_T("Failed to Initialize Sockets"), MB_OK | MB_ICONSTOP);
   return FALSE;
}

注意事项:

         Socket通信客户端的初始化可以分为两种方法,一种是通过上一节中提到的初始化封装类进行Socket的初始化。第二种是通过AfxSocketInit()Socket进行初始化。AfxSocketInit()初始化需要注意的是需要添加头文件#include<afxsock.h>,并在应用程序InitInstance()进行初始化。如下所示:

BOOL CMFCApplicationSocketClientDemoApp::InitInstance()
{

	INITCOMMONCONTROLSEX InitCtrls;
	InitCtrls.dwSize = sizeof(InitCtrls);
	InitCtrls.dwICC = ICC_WIN95_CLASSES;
	InitCommonControlsEx(&InitCtrls);
	
	CWinApp::InitInstance();

	if (!AfxSocketInit())
	{
		AfxMessageBox(_T("Windows套接字初始化失败!"));
		return FALSE;
	}

	AfxEnableControlContainer();

	CShellManager *pShellManager = new CShellManager;

	CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));

	SetRegistryKey(_T("应用程序向导生成的本地应用程序"));

	CMFCApplicationSocketClientDemoDlg dlg;
	m_pMainWnd = &dlg;
	INT_PTR nResponse = dlg.DoModal();
	if (nResponse == IDOK)
	{
	
	}
	else if (nResponse == IDCANCEL)
	{

	}
	else if (nResponse == -1)
	{
		TRACE(traceAppMsg, 0, "警告: 对话框创建失败,应用程序将意外终止。\n");
		TRACE(traceAppMsg, 0, "警告: 如果您在对话框上使用 MFC 控件,则无法 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS。\n");
	}

	if (pShellManager != nullptr)
	{
		delete pShellManager;
	}

#if !defined(_AFXDLL) && !defined(_AFX_NO_MFC_CONTROLS_IN_DIALOGS)
	ControlBarCleanUp();
#endif
	return FALSE;
}

        通过自定义类对Socket进行初始化。必须包含自定义类头文件#include"CSoceketInitConfig.h",在应用程序中通过如下代码进行初始化。本类在定义时成员函数被定义为内联函数。

#include<iostream>
#include<winsock.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
#pragma once
class CSoceketInitConfig
{
public:
	CSoceketInitConfig(BYTE minorVer = 2, BYTE majorVer = 2)
	{
		WORD	w_req = MAKEWORD(2, 2);
		WSADATA wsadata;
		int     erro;

		erro = WSAStartup(w_req, &wsadata);
		if (erro != 0)
		{
			printf("初始化嵌套字失败!\n");
		}
		else
		{
			printf("初始化嵌套字成功!\n");
		}

		if (LOBYTE(wsadata.wVersion) != 2 || LOBYTE(wsadata.wHighVersion) != 2)
		{
			printf("嵌套字版本号检测不符!\n");
		}
		else
		{
			printf("嵌套字版本号检测正确!\n");
		}
	}
};

CSoceketInitConfig ClientSockInit(2,2);

        应用程序头文件源代码:

#include"CSoceketInitConfig.h"
#include "afxwin.h"
#include<iostream>
#include<winsock.h>
#pragma comment(lib,"ws2_32.lib")
#include "afxdialogex.h"

using namespace std;
#pragma once
#pragma warning(disable:4996)
#pragma warning(disable:6263)
#pragma warning(disable:6255)
#pragma warning(disable:6387)
#pragma warning(disable:26454)

const int      PORTSET             = 8000;
#define        MaxBufSize           2048

class CMFCApplicationSocketClientDemoDlg : public CDialogEx
{

public:
	CMFCApplicationSocketClientDemoDlg(CWnd* pParent = nullptr);	


#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_MFCAPPLICATIONSOCKETCLIENTDEMO_DIALOG };
#endif

	protected:
	virtual			void DoDataExchange(CDataExchange* pDX);	


protected:
	HICON			m_hIcon;

	virtual			BOOL OnInitDialog();
	afx_msg			void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg			void OnPaint();
	afx_msg			HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()
public:
	CEdit			m_ClientRecvMsg;
	CButton			m_ConnectServer;
	CButton			m_CutDownConnect;
	SOCKET          m_pClientSock;
	BOOL            m_ServerConnectSucced;
	afx_msg			void OnBnClickedButtonsendmsg();
	afx_msg         char* CstringToWideCharArry(CString CstrText);
	afx_msg         CString CharArryToCstring(char* CharText);
	afx_msg			void OnBnClickedButtonconnectserver();
	afx_msg         BOOL ConnectServerSocket(CMFCApplicationSocketClientDemoDlg*);
	afx_msg		    CString GetSystemTime();
	afx_msg		    void SetRevTextMsg(CString nText);
	afx_msg			void OnEnChangeEditsend();
	CButton			m_SendMsgToServer;
	afx_msg void    OnBnClickedButtonconnectcunt();
};
DWORD               WINAPI ConnectServerThread(LPCVOID lParam);
BOOL                socket_Select(SOCKET hSocket, DWORD nTimeOut, BOOL bRead);

      应用程序CPP文件源代码:最近很忙,程序写的较为匆忙,能正常运行,后期根据自己需要进行更改完善,文件发送的功能后期会陆续补上。


#include "pch.h"
#include "framework.h"
#include "MFCApplicationSocketClientDemo.h"
#include "MFCApplicationSocketClientDemoDlg.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#endif


class CAboutDlg : public CDialogEx
{
public:
	CAboutDlg();


#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_ABOUTBOX };
#endif

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);   

protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


CMFCApplicationSocketClientDemoDlg::CMFCApplicationSocketClientDemoDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_MFCAPPLICATIONSOCKETCLIENTDEMO_DIALOG, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	m_pClientSock = NULL;
	m_ServerConnectSucced = FALSE;
}

void CMFCApplicationSocketClientDemoDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_EDITRECEV, m_ClientRecvMsg);
	//  DDX_Control(pDX, IDC_EDITSEND, m_ClientSendMsg);
	//  DDX_Control(pDX, IDC_IPADDRESS_SERVER, m_ServerIPaddr);
	//  DDX_Control(pDX, IDC_EDITSERVERPORT, m_ServerPort);
	DDX_Control(pDX, IDC_BUTTONCONNECTSERVER, m_ConnectServer);
	DDX_Control(pDX, IDC_BUTTONCONNECTCUNT, m_CutDownConnect);
	DDX_Control(pDX, IDC_BUTTONSENDMSG, m_SendMsgToServer);
}

BEGIN_MESSAGE_MAP(CMFCApplicationSocketClientDemoDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTONSENDMSG, &CMFCApplicationSocketClientDemoDlg::OnBnClickedButtonsendmsg)
	ON_BN_CLICKED(IDC_BUTTONCONNECTSERVER, &CMFCApplicationSocketClientDemoDlg::OnBnClickedButtonconnectserver)
	ON_EN_CHANGE(IDC_EDITSEND, &CMFCApplicationSocketClientDemoDlg::OnEnChangeEditsend)
	ON_BN_CLICKED(IDC_BUTTONCONNECTCUNT, &CMFCApplicationSocketClientDemoDlg::OnBnClickedButtonconnectcunt)
END_MESSAGE_MAP()


BOOL CMFCApplicationSocketClientDemoDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != nullptr)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}


	SetIcon(m_hIcon, TRUE);			
	SetIcon(m_hIcon, FALSE);		
	//ShowWindow(SW_MAXIMIZE);
	//ShowWindow(SW_MINIMIZE);
	UpdateData(TRUE);
    SetDlgItemText(IDC_IPADDRESS_SERVER,_T("127.0.0.1"));
	::HideCaret(GetDlgItem(IDC_EDITSEND)->GetSafeHwnd());
	::HideCaret(GetDlgItem(IDC_EDITRECEV)->GetSafeHwnd());
	SetDlgItemInt(IDC_EDITSERVERPORT, PORTSET);
	SetDlgItemText(IDC_EDITSERVERPORT, _T("8000"));
	m_CutDownConnect.EnableWindow(FALSE);
	m_ConnectServer.EnableWindow(TRUE);
	UpdateData(FALSE);
	return TRUE;  
}

void CMFCApplicationSocketClientDemoDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else if ((nID & 0xFFF0) == SC_SIZE)
	{
		return;
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}


void CMFCApplicationSocketClientDemoDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); 

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;


		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}


HCURSOR CMFCApplicationSocketClientDemoDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}


void CMFCApplicationSocketClientDemoDlg::OnBnClickedButtonsendmsg()
{
	char* Pmsg;
	CString strGetMsg;
	int iWrite;
	GetDlgItemText(IDC_EDITSEND, strGetMsg);
	Pmsg = CstringToWideCharArry(strGetMsg);
	iWrite = send(m_pClientSock, Pmsg, _tcslen(strGetMsg)*sizeof(Pmsg), 0);
	if (SOCKET_ERROR == iWrite) 
	{
		SetRevTextMsg(_T("本机发送消息:") +strGetMsg +_T("失败!"));	
	}
	else
	{
		SetRevTextMsg(_T("本机发送消息: >>") + strGetMsg+_T("成功!"));
	}	
	SetDlgItemText(IDC_EDITSEND, _T(""));	
}

BOOL socket_Select(SOCKET hSocket, DWORD nTimeOut, BOOL bRead)
{
	{
		FD_SET fdset;
		timeval tv;
		FD_ZERO(&fdset);
		FD_SET(hSocket, &fdset);
		nTimeOut = nTimeOut > 1000 ? 1000 : nTimeOut;
		tv.tv_sec = 0;
		tv.tv_usec = nTimeOut;
		int iRet = 0;
		if (bRead)
		{
			iRet = select(0, &fdset, NULL, NULL, &tv);
		}
		else
		{
			iRet = select(0, NULL, &fdset, NULL, &tv);
		}
		if (iRet <= 0)
		{
			return FALSE;
		}
		else if (FD_ISSET(hSocket, &fdset))
		{
			return TRUE;
		}
		return FALSE;
	}
}

char* CMFCApplicationSocketClientDemoDlg::CstringToWideCharArry(CString CstrText)
{
	int lth = WideCharToMultiByte(CP_ACP, 0, CstrText, CstrText.GetLength(), NULL, 0, NULL, NULL);
	char* pStr = (char*)malloc((lth + 1) * sizeof(char));
	ASSERT(pStr!=NULL);
	memset(pStr, 0, (lth + 1) * sizeof(char));
	WideCharToMultiByte(CP_ACP, 0, CstrText.GetBuffer(), CstrText.GetLength(), (LPSTR)pStr, lth, NULL, NULL);
	*(pStr + lth + 1) = '\0';
	printf("lth=%d", lth);
	printf("lth+1=%d", (lth + 1) * sizeof(char));
	printf("LthStr=%d", sizeof(CString));
	printf("CharLen=%d", sizeof(char*));
	return  pStr;
}

CString CMFCApplicationSocketClientDemoDlg::CharArryToCstring(char* CharText)
{
	int charLth = strlen(CharText);
	int len = MultiByteToWideChar(CP_ACP, 0, CharText, charLth, NULL, 0);
	TCHAR* buf = new TCHAR[len + 1];
	MultiByteToWideChar(CP_ACP, 0, CharText, charLth, buf, len);
	buf[len] = '\0';
	CString pWideChar;
	pWideChar.Append(buf);
	return pWideChar;
}


void CMFCApplicationSocketClientDemoDlg::OnBnClickedButtonconnectserver()
{
	CreateThread(0, 0, (LPTHREAD_START_ROUTINE)ConnectServerThread, this, 0, NULL);
}

BOOL CMFCApplicationSocketClientDemoDlg::ConnectServerSocket(CMFCApplicationSocketClientDemoDlg* pClient)
{
	CSoceketInitConfig ClientSockInit(2,2);

	m_pClientSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (m_pClientSock==NULL)
	{
		MessageBox(_T("ClientSocket创建失败!"),_T("信息提示:"),MB_OKCANCEL|MB_ICONERROR);
		return FALSE;
	}
	sockaddr_in ServerAddr_in;
	ServerAddr_in.sin_family = AF_INET;

	int m_SerPort = GetDlgItemInt(IDC_EDITSERVERPORT);
	CString StrSerIp;
	GetDlgItemText(IDC_IPADDRESS_SERVER,StrSerIp);
	
	if (StrSerIp==_T("0.0.0.0")||m_SerPort > 65535 || m_SerPort < 1024|| m_SerPort==0)
	{
		MessageBox(_T("请输入正确端口IP地址,重新连接!"), _T("信息提示:"), MB_OK | MB_ICONINFORMATION);
		SetRevTextMsg(_T("请输入正确端口IP地址,重新连接"));
		return FALSE;
	}
	char* pStrIP = CstringToWideCharArry(StrSerIp);

	ServerAddr_in.sin_port = htons(m_SerPort);
	ServerAddr_in.sin_addr.S_un.S_addr = inet_addr(pStrIP);
	if (SOCKET_ERROR==connect(m_pClientSock, (sockaddr*)&ServerAddr_in, sizeof(ServerAddr_in)))
	{
		MessageBox(_T("服务器连接失败,请检查你填写的IP和端口是否错误!"), _T("信息提示:"), MB_OK | MB_ICONWARNING);
		SetRevTextMsg(_T("服务器连接失败,请检查你填写的IP和端口是否错误!"));
		return FALSE;
	}
	pClient->SetRevTextMsg(_T("连接服务器成功"));
	pClient->m_CutDownConnect.EnableWindow( TRUE);
	pClient->m_ConnectServer.EnableWindow(FALSE);
	m_ServerConnectSucced = TRUE;

	CString RevMsg;
	while (true)
	{
		if (socket_Select(m_pClientSock,100,TRUE))
		{
			char recvBuff[MaxBufSize] = { 0 };
			int iRead = recv(m_pClientSock, recvBuff, sizeof(recvBuff), 0);
			if (iRead > 0)
			{
				RevMsg = CharArryToCstring(recvBuff);
				pClient->SetRevTextMsg(StrSerIp + _T(">>") + RevMsg);
			}
			else
			{
				pClient->SetRevTextMsg(_T("已断线,请重新连接"));
				pClient->m_CutDownConnect.EnableWindow(FALSE);
				pClient->m_ConnectServer.EnableWindow(TRUE);
				m_ServerConnectSucced = FALSE;
				return TRUE;
			}
		}
		
	}
	return TRUE;
}

CString CMFCApplicationSocketClientDemoDlg::GetSystemTime()
{
	CString m_CurrentTime;
	CTime m_GetTime = CTime::GetTickCount();
	m_CurrentTime = m_GetTime.Format(_T("%Y/%m/%d:%H:%M:%S"));
	return m_CurrentTime;
}

void CMFCApplicationSocketClientDemoDlg::SetRevTextMsg(CString nText)
{
	CString str;
	GetDlgItemText(IDC_EDITRECEV, str);
	LONG lth = str.GetLength();
	m_ClientRecvMsg.SetSel(lth, lth,TRUE);
	m_ClientRecvMsg.SetFocus();
	m_ClientRecvMsg.ReplaceSel(GetSystemTime() + _T("\r\n") + nText + _T("\r\n"));
}

DWORD WINAPI ConnectServerThread(LPCVOID lParam)
{
	CMFCApplicationSocketClientDemoDlg* pClient = (CMFCApplicationSocketClientDemoDlg*)lParam;
	if (pClient->ConnectServerSocket(pClient))
	{

	}
	return 0;
}


void CMFCApplicationSocketClientDemoDlg::OnEnChangeEditsend()
{
	CString m_Msg_Enter;
	GetDlgItemText(IDC_EDITSEND, m_Msg_Enter);
	if (m_Msg_Enter == _T("") || !m_ServerConnectSucced)
	{
		m_SendMsgToServer.EnableWindow(FALSE);
	}
	else
	{
		m_SendMsgToServer.EnableWindow(TRUE);
	}
}


void CMFCApplicationSocketClientDemoDlg::OnBnClickedButtonconnectcunt()
{
	closesocket(m_pClientSock);
	m_ServerConnectSucced = FALSE;
	m_CutDownConnect.EnableWindow(FALSE);
    m_ConnectServer.EnableWindow(TRUE);
}

 参考文献:

        VS 2019 MFC Socket 通讯例程服务器端Select一对多同步通信TCP/IP通信服务器端[一]_lzc881012的博客-CSDN博客TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,是一个工业标准的协议集,它是为广域网(WANs)设计的。3>原始套接字(SOCK_RAW):它提供一种能力,让我们直接跨越传输层,直接对IP层进行数据封装,通过该套接字,我们可以直接将数据封装成IP层能够认识的协议格式。1>流方套接字(SOCK_STREAM):它对应TCP协议,它提供面向连接的、可靠的数据传输服务,数据无差错、无重复的发送,且按发送顺序接收。https://blog.csdn.net/lzc881012/article/details/127737864?spm=1001.2014.3001.5501

有关VS 2019 MFC Socket 通讯例程客户端Connect连接一对多同步通信TCP/IP通信客户端[二]的更多相关文章

  1. ruby-on-rails - Rails 应用程序之间的通信 - 2

    我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

  2. ruby - 续集在添加关联时访问many_to_many连接表 - 2

    我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以

  3. ruby - 无法在 60 秒内获得稳定的 Firefox 连接 (127.0.0.1 :7055) - 2

    我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类

  4. MIMO-OFDM无线通信技术及MATLAB实现(1)无线信道:传播和衰落 - 2

     MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO

  5. ruby - 我的 Ruby IRC 机器人没有连接到 IRC 服务器。我究竟做错了什么? - 2

    require"socket"server="irc.rizon.net"port="6667"nick="RubyIRCBot"channel="#0x40"s=TCPSocket.open(server,port)s.print("USERTesting",0)s.print("NICK#{nick}",0)s.print("JOIN#{channel}",0)这个IRC机器人没有连接到IRC服务器,我做错了什么? 最佳答案 失败并显示此消息::irc.shakeababy.net461*USER:Notenoughparame

  6. ruby-on-rails - 连接字符串时如何在 <%=%> block 内输出 html_safe? - 2

    考虑一下:现在这些情况:#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2我需要用其他字符串输出URL。我如何保证&符号不会被转义?由于我无法控制的原因,我无法发送&。求助!把我的头发拉到这里:\编辑:为了澄清,我实际上有一个像这样的数组:@images=[{:id=>"fooid",:url=>"http://

  7. ruby - Faye WebSocket,关闭处理程序被触发后重新连接到套接字 - 2

    我有一个super简单的脚本,它几乎包含了FayeWebSocketGitHub页面上用于处理关闭连接的内容:ws=Faye::WebSocket::Client.new(url,nil,:headers=>headers)ws.on:opendo|event|p[:open]#sendpingcommand#sendtestcommand#ws.send({command:'test'}.to_json)endws.on:messagedo|event|#hereistheentrypointfordatacomingfromtheserver.pJSON.parse(event.d

  8. ruby - 在 TCPServer (Ruby) 中,我如何从客户端获取 IP/MAC? - 2

    我想在Ruby的TCPServer中获取客户端的IP地址。以及(如果可能的话)MAC地址。例如,Ruby中的时间服务器,请参阅评论。tcpserver=TCPServer.new("",80)iftcpserverputs"Listening"loopdosocket=tcpserver.acceptifsocketThread.newdoputs"Connectedfrom"+#HERE!HowcanigettheIPAddressfromtheclient?socket.write(Time.now.to_s)socket.closeendendendend非常感谢!

  9. ruby-on-rails - 什么会导致与 APNS 的连接间歇性断开连接? - 2

    我有一个ruby​​脚本可以打开与Apple推送服务器的连接并发送所有待处理的通知。我看不出任何原因,但当Apple断开我的脚本时,我遇到了管道损坏错误。我已经编写了我的脚本来适应这种情况,但我宁愿只是找出它发生的原因,这样我就可以在第一时间避免它。它不会始终根据特定通知断开连接。它不会以特定的字节传输大小断开连接。一切似乎都是零星的。您可以在单个连接上发送的数据传输或有效负载计数是否有某些限制?看到人们的解决方案始终保持一个连接打开,我认为这不是问题所在。我看到连接在3次通知后断开,我看到它在14次通知后断开。我从未见过它能超过14点。有没有人遇到过这种类型的问题?如何处理?

  10. ruby - 如何断开现有的 ruby​​ 续集与数据库的连接? - 2

    我的意思是之前建立的那个DB=Sequel.sqlite('my_blog.db')或DB=Sequel.connect('postgres://user:password@localhost/my_db')或DB=Sequel.postgres('my_db',:user=>'user',:password=>'password',:host=>'localhost')等等。Sequel::Database类没有名为“disconnect”的公共(public)实例方法,尽管它有一个“connect”。也许有人已经遇到过这个问题。我将不胜感激。 最佳答案

随机推荐