Ⅰ MFC SOCKET編程 10048錯誤!!!
……你要不要試試看以管理員身份運行?
10048是埠被佔用,但是換了好幾個也不行就懷疑是不是沒許可權了
另:試試看把所謂的系統安全軟體關掉?猜測,只是猜測,這類軟體有的有可能會做出阻止埠監聽的事情來
Ⅱ mfc中套接字socket的用法
學習這個類,首先需要了解基本的TCP/IP 和UDP 協議,對埠…………都有一定的理解……以下是我總結的重要的幾點,希望對你有用……有不懂得可以到我空間提問……
1.利用Tcp協議編程
1)伺服器端:
a)建立TCP監聽器TcpListener對象。
TcpListener tl=new TcpListener(埠號);
b)啟動監聽器
tl.Start();
c)用監聽器獲取連接進來的套接字(Socket)
Socket s=myList.AcceptSocket();
d)通過Socket的Receive方法獲取客戶端發送的數據
byte [] result=new byte[1024];
int k=s.Receive(result);
e)通過Socket的Send方法向客戶端發送數據
byte[] st=System.Text.Encoding.Default.GetBytes(「text」);
s.Send(st);
f)在通訊結束後,需要釋放資源結束監聽
s.Close();
tl.Stop();
2)客戶端:
a)建立TCP客戶端TcpClient對象。
TcpClient tcpclnt = new TcpClient();
b)連接伺服器
tcpclnt.Connect(IP地址字元串,埠號);
c)獲得客戶端網路傳輸 流
Stream stm =tcpclnt.GetStream();
d)通過Stream的Write方法向伺服器端發送的數據
e)通過Stream的Read方法讀取伺服器段發來的數據
f)在通訊結束後,需要釋放資源,結束和伺服器的連接
tcpclnt.Close();
2.利用UDP協議編程
a)建立UDP客戶端UdpClient對象。
UdpClient uc=new UdpClient(埠號);
b)連接對方遠程主機
uc.Connect(IP地址,對方遠程主機的埠號);
c)通過uc的Receive方法獲取遠程主機發送來的數據
IPEndPoint ip=new IPEndPoint(IPAddress.Parse(IP字元串),埠號);
byte[] b=uc.Receive(ref ip);
e)通過uc的Send方法向遠程主機發送數據
byte[] st=System.Text.Encoding.Default.GetBytes(「text」);
uc.Send(st);
f)在通訊結束後,需要釋放資源
uc.Close();
Ⅲ vc++6.0編的基於MFC的簡單的tcp聊天程序
4.1伺服器端代碼
開啟伺服器功能:
void OnServerOpen() //開啟伺服器功能
{
WSADATA wsaData;
int iErrorCode;
char chInfo[64];
if (WSAStartup(WINSOCK_VERSION, &wsaData)) //調用Windows Sockets DLL
{ MessageBeep(MB_ICONSTOP);
MessageBox("Winsock無法初始化!", AfxGetAppName(), MB_OK|MB_ICONSTOP);
WSACleanup();
return; }
else
WSACleanup();
if (gethostname(chInfo, sizeof(chInfo)))
{ ReportWinsockErr("\n無法獲取主機!\n ");
return; }
CString csWinsockID = "\n==>>伺服器功能開啟在埠:No. ";
csWinsockID += itoa(m_pDoc->m_nServerPort, chInfo, 10);
csWinsockID += "\n";
PrintString(csWinsockID); //在程序視圖顯示提示信息的函數,讀者可自行創建
m_pDoc->m_hServerSocket=socket(PF_INET, SOCK_STREAM, DEFAULT_PROTOCOL);
//創建伺服器端Socket,類型為SOCK_STREAM,面向連接的通信
if (m_pDoc->m_hServerSocket == INVALID_SOCKET)
{ ReportWinsockErr("無法創建伺服器socket!");
return;}
m_pDoc->m_sockServerAddr.sin_family = AF_INET;
m_pDoc->m_sockServerAddr.sin_addr.s_addr = INADDR_ANY;
m_pDoc->m_sockServerAddr.sin_port = htons(m_pDoc->m_nServerPort);
if (bind(m_pDoc->m_hServerSocket, (LPSOCKADDR)&m_pDoc->m_sockServerAddr,
sizeof(m_pDoc->m_sockServerAddr)) == SOCKET_ERROR) //與選定的埠綁定
{ReportWinsockErr("無法綁定伺服器socket!");
return;}
iErrorCode=WSAAsyncSelect(m_pDoc->m_hServerSocket,m_hWnd,
WM_SERVER_ACCEPT, FD_ACCEPT);
//設定伺服器相應的網路事件為FD_ACCEPT,即連接請求,
// 產生相應傳遞給窗口的消息為WM_SERVER_ACCEPT
if (iErrorCode == SOCKET_ERROR)
{ ReportWinsockErr("WSAAsyncSelect設定失敗!");
return;}
if (listen(m_pDoc->m_hServerSocket, QUEUE_SIZE) == SOCKET_ERROR) //開始監聽客戶連接請求
{ReportWinsockErr("伺服器socket監聽失敗!");
m_pParentMenu->EnableMenuItem(ID_SERVER_OPEN, MF_ENABLED);
return;}
m_bServerIsOpen = TRUE; //監視伺服器是否打開的變數
return;
}
響應客戶發送聊天文字到伺服器:ON_MESSAGE(WM_CLIENT_READ, OnClientRead)
LRESULT OnClientRead(WPARAM wParam, LPARAM lParam)
{
int iRead;
int iBufferLength;
int iEnd;
int iRemainSpace;
char chInBuffer[1024];
int i;
for(i=0;(i
//MAXClient是伺服器可響應連接的最大數目
{}
if(i==MAXClient) return 0L;
iBufferLength = iRemainSpace = sizeof(chInBuffer);
iEnd = 0;
iRemainSpace -= iEnd;
iBytesRead = recv(m_aClientSocket[i], (LPSTR)(chInBuffer+iEnd), iSpaceRemaining, NO_FLAGS);
//用可控緩沖接收函數recv()來接收字元
iEnd+=iRead;
if (iBytesRead == SOCKET_ERROR)
ReportWinsockErr("recv出錯!");
chInBuffer[iEnd] = '\0';
if (lstrlen(chInBuffer) != 0)
{PrintString(chInBuffer); //伺服器端文字顯示
OnServerBroadcast(chInBuffer); //自己編寫的函數,向所有連接的客戶廣播這個客戶的聊天文字
}
return(0L);
}
對於客戶斷開連接,會產生一個FD_CLOSE消息,只須相應地用closesocket()關閉相應的Socket即可,這個處理比較簡單。
4.2客戶端代碼
連接到伺服器:
void OnSocketConnect()
{ WSADATA wsaData;
DWORD dwIPAddr;
SOCKADDR_IN sockAddr;
if(WSAStartup(WINSOCK_VERSION,&wsaData)) //調用Windows Sockets DLL
{MessageBox("Winsock無法初始化!",NULL,MB_OK);
return;
}
m_hSocket=socket(PF_INET,SOCK_STREAM,0); //創建面向連接的socket
sockAddr.sin_family=AF_INET; //使用TCP/IP協議
sockAddr.sin_port=m_iPort; //客戶端指定的IP地址
sockAddr.sin_addr.S_un.S_addr=dwIPAddr;
int nConnect=connect(m_hSocket,(LPSOCKADDR)&sockAddr,sizeof(sockAddr)); //請求連接
if(nConnect)
ReportWinsockErr("連接失敗!");
else
MessageBox("連接成功!",NULL,MB_OK);
int iErrorCode=WSAAsyncSelect(m_hSocket,m_hWnd,WM_SOCKET_READ,FD_READ);
//指定響應的事件,為伺服器發送來字元
if(iErrorCode==SOCKET_ERROR)
MessageBox("WSAAsyncSelect設定失敗!");
}
接收伺服器端發送的字元也使用可控緩沖接收函數recv(),客戶端聊天的字元發送使用數據可控緩沖發送函數send(),這兩個過程比較簡單,在此就不加贅述了。
Ⅳ mfc socket 編程的流程是怎麼樣的
初始化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);
}
Ⅳ MFC中提供socket通信功能的類有幾個類名是什麼用示意圖簡述socket的TCP(有連接的)
MFC 最常用的socket類就是CSocket類了,AfxSocketInit()封裝了套接字的版本的請求和套接字的釋放等。具體實現函數參考MSDN.
TCP 連接示意圖我就懶的找了,網上隨便找下都是。我按照我的理解給你寫個吧。
TCP(面向連接)Socket 編程
服務端
1. 創建套接字(Socket)
2.將套接字綁定到一個本地地址和埠上(bind)
3.將套接字設為監聽模式,等待客戶端連接(listen)
4.當請求到來時,接收該請求,並返回一個新的對應於此次連接的套接字(accept)
5.用返回的套接字和客戶端進行數據局傳輸(send /recv)
6.返回等待另一個客戶請求
7.關閉套接字
客戶端
1.創建套接字,(socket)
2.向伺服器發出連接請求,(connect)
3.和服務端進行通信(send/recv)
4. 關閉套接字。
基本流程就是這樣子,具體還要你自己親自上機編寫。感受這樣的流程。還有什麼不懂的,可以問我,共同進步。。。
Ⅵ C++ socket編程 和 MFC socket編程 有什麼區別
其實,不用說的太多。C++就是純的利用socket進行網路通信編程。MFC就是基於圖形界面進行網路通信編程。它們所調用的類庫不一樣。
補充一下答案:
C++ socket典型的調用方式是利用:非同步套接字 WSASocket TCP
MFC socket典型的調用方式是利用:CSocket
這兩者有本質區別。
Ⅶ mfc中用TCP/IP socket編程來寫了一個簡單的收發端,可客戶端的accept()老連接不上
你的意思是不是服務端卡在accept()那,然後客戶端彈出「連接失敗!」窗口?
如果是這樣的話先檢查網路連接是否正常,然後IP是不是對的
如果以上都沒問題,用WSAGetLastError()得到錯誤代碼並在MessageBox()中顯示。
另外發現你用阻塞方式收發數據,最好將這兩段代碼放入新線程,否則容易卡死
附上WSAGetLastError()錯誤代碼:
WSAENOTINITIALISED:在使用此API之前應首先成功地調用WSAStartup()。
WSAENETDOWN:WINDOWS套介面實現檢測到網路子系統失效。
WSAEADDRINUSE:所指的地址已在使用中。
WSAEINTR:通過一個WSACancelBlockingCall()來取消一個(阻塞的)調用。
WSAEINPROGRESS:一個阻塞的WINDOWS套介面調用正在運行中。
WSAEADDRNOTAVAIL:在本地機器上找不到所指的地址。
WSAENOTSUPPORT:所指族中地址無法與本套介面一起使用。
WSAECONNREFUSED:連接嘗試被強制拒絕。
WSAEDESTADDREQ:需要目的地址。
WSAEFAULT:namelen參數不正確。
WSAEINVAL:套介面沒有準備好與一地址捆綁。
WSAEISCONN:套介面早已連接。
WSAEMFILE:無多餘文件描述字。
WSAENETUNREACH:當前無法從本主機訪問網路。
WSAENOBUFS:無可用緩沖區。套介面未被連接。
WSAENOTSOCK:描述字不是一個套介面。
WSAETIMEOUT:超時時間到。
WSAEWOULDBLOCK:套介面設置為非阻塞方式且連接不能立即建立。可用select()調用對套介面寫,因為select()時會進行連接。
希望對你有幫肋..