为了账号安全,请及时绑定邮箱和手机立即绑定

请问我该怎么和单独的一个客户机通信啊?

请问我该怎么和单独的一个客户机通信啊?

噜噜哒 2023-03-20 16:12:34
服务端监听,一堆客户端连接, 看了点教程,只会在客户端连接的时候通信,其他的时候要怎么通信啊?
查看完整描述

1 回答

?
拉莫斯之舞

TA贡献1820条经验 获得超10个赞

初始化socket
首先需要调用AfxSocketInit()函数来初始化我们的socket环境。
为了初始化sockets,我们需要调用AfxSocketInit()函数。它通常是在MFC中的InitInstance()函数中被调用的。如果我们用程序向导来创建socket程序的话,查看“use Windows Sockets”这个选项,然后选中它。它将会自动的为我们创建这个步骤了。(如果我们没有选中这个选项的话,我们也可以手动添加这些代码的。)这个函数的返回值显示这个函数的调用成功或失败。
BOOL CServerApp::InitInstance()
{....
if( AfxSocketInit() == FALSE)

AfxMessageBox("Sockets Could Not Be Initialized"); 
return FALSE; 
}
...
}
创建Server Sockets
为了创建一个Server Socket,我们需要声明一个CAyncSocket的变量或者我们自己定制的一个从AyncSocket或是Cscket继承来的类的类型的变量。然后调用Create()函数,同时指定监听的端口。这个函数的返回值显示这个函数的调用成功或失败。
UpdateData(TRUE);
m_sListener.Create(m_port);
if(m_sListener.Listen()==FALSE) 

AfxMessageBox("Unable to Listen on that port,please try another port"); 
m_sListener.Close(); 
return; 
}
创建Client Sockets
为了创建Client socket类,我们需要声明一个CAyncSocket的变量或者我们自己定制的一个从AyncSocket或是Cscket继承来的类的类型的变量。然后调用Create()函数,同时指定监听的端口。这个函数的返回值显示这个函数的调用成功或失败。
m_sConnected.Create();
m_sConnected.Connect("server ip",port);
监听客户端的连接
创建了server socket以后,我们要进行监听。调用Listen()函数。这个函数的返回值显示这个函数的调用成功或失败。
if( m_sListener.Listen()== FALSE) 

AfxMessageBox("Unable to Listen on that port,please try another port"); 
m_sListener.Close(); 
return;
}
接受连接
连接请求要被接受accept,是用另外的socket,不是正在监听的socket。请参看代码。
void CXXXDlg::OnAccept()
{
CString strIP; 
UINT port; 
if(m_sListener.Accept(m_sConnected)) 
{
m_sConnected.GetSockName(strIP,port); //应该是GetPeerName,获取对方的IP和port
m_status="Client Connected,IP :"+ strIP; 
m_sConnected.Send("Connected To Server",strlen("Connected To Server"));  
UpdateData(FALSE); 
}
else 

AfxMessageBox("Cannoot Accept Connection"); 

}
发送数据
数据放在一个buffer中或是结构体中,调用send()函数发送。
m_sConnected.Send(pBuf,iLen);
接受数据
调用receive()接受数据。
void CXXXrDlg::OnReceive() 

char *pBuf =new char [1025]; 
CString strData; 
int iLen;
iLen=m_sConnected.Receive(pBuf,1024);  
if(iLen == SOCKET_ERROR)  
{
AfxMessageBox("Could not Recieve");  
}  
else  

pBuf[iLen]=NULL;
strData=pBuf;
m_recieveddata.Insert(m_recieveddata.GetLength(),strData); 
//display in server  
UpdateData(FALSE); 
m_sConnected.Send(pBuf,iLen); //send the data back to the Client  
delete pBuf;  

}
关闭连接
m_sConnected.ShutDown(0); 停止发送数据
m_sConnected.ShutDown(1); 停止接受数据
m_sConnected.ShutDown(2); 停止发送接受数据
m_sConnected.Close();
编写自己的socket类
在class view中选择添加一个新类,设置它的基类为CAsyncSocket,在类向导的帮助下添加如下的一些函数。
class MySocket : public CAsyncSocket
{ // Attributes 
public: 
// Operations
public: 
MySocket(); 
virtual ~MySocket(); 
// Overrides 
public: 
void SetParentDlg(CDialog *pDlg);// ClassWizard generated virtual function overrides 
//{{AFX_VIRTUAL(MySocket) 
public: 
virtual void OnAccept(int nErrorCode);
virtual void OnClose(int nErrorCode);
virtual void OnConnect(int nErrorCode);
virtual void OnOutOfBandData(int nErrorCode);
virtual void OnReceive(int nErrorCode); 
virtual void OnSend(int nErrorCode); 
//}}AFX_VIRTUAL // Generated message map functions 
//{{AFX_MSG(MySocket) 
// NOTE - the ClassWizard will add and remove member functions here. //}}AFX_MSG 
protected: 
private:
CDialog * m_pDlg; 
};
设置“Parent Dialog”
调用这个socket类的SetParentDlg函数,保证当socket事件发生的时候这个窗体能接收到。
m_sListener.SetParentDlg(this); 
m_sConnected.SetParentDlg(this);
建立Socket 事件和窗体成员函数之间的联系
在这个窗体类中添加一些函数,比如void OnReceive(); void OnClose(); void OnAccept(); void OnConnect()等,它们会在我们编写的的socket类中调用到。
void MySocket::OnAccept(int nErrorCode) 

// TODO: Add your specialized code here and/or call the base class 
if(nErrorCode==0) 

((CServerDlg*)m_pDlg)->OnAccept(); 
}
CAsyncSocket::OnAccept(nErrorCode); 
}

 


查看完整回答
反对 回复 2023-03-22
  • 1 回答
  • 0 关注
  • 64 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信