1. 程式人生 > >MFC Socket網路程式設計之TCP客戶端

MFC Socket網路程式設計之TCP客戶端

如果想要做一個和Socket有關的MFC軟體, 在建立基本對話方塊時需要點選Windows套接字;然後方可進行Socket有關操作;

如果沒有點,可以在標頭檔案之前寫上 #pragma comment (lib, "ws2_32.lib"); 

包含標頭檔案#include <Winsock.h>

建立一個服務端程式步驟如下:

 1,建立套接字(socket);

2, 將套接字繫結到一個本地地址和埠上(bind);

3, 將套接字設為監聽模式,準備接受客戶請求(listen);

4, 等待客戶請求到來,當請求到來後,接受連線請求,返回一個新的對應於此次連線的套接字(accept);

5, 用返回的套接字和客戶端進行通訊(send/ recv);

6, 返回等待另一客戶請求;

7, 關閉套接字;

以上前4步都是線上程函式中完成的,因為伺服器端要一直處於監聽狀態;

建立一個客戶端程式步驟如下:

1, 建立套接字(socket);

2, 向伺服器傳送連線請求(connect);

3, 和伺服器進行通訊(send/ recv);

4, 關閉套接字;

客戶端程式碼如下:

建立一個基本對話方塊應用程式,新增如下控制元件,並對接收框做如下設定;


2, 添加發送資料函式

void CcFileDlg::OnBnClickedSend()
{
	CString s;
	char * msg;
	send_edit.GetWindowText(s);
	msg = s.GetBuffer(s.GetLength());
	if (send(sock, msg, strlen(msg), 0) == SOCKET_ERROR)
	{
		update("傳送失敗");
	}
	else if (s == "")
	{
		MessageBox("請輸入資訊");
	}
	else
	{
		update("client:" + s);//訊息上屏,清空輸入,並重獲焦點
		send_edit.SetWindowText("");
		send_edit.SetFocus();
	}
	// TODO: 在此新增控制元件通知處理程式程式碼
}

3,新增連線伺服器函式
void CcFileDlg::OnBnClickedbtnconnect()
{
	WSADATA wsaData;
	SOCKADDR_IN server_addr;
	WORD wVersion;
	wVersion = MAKEWORD(2, 2);
	WSAStartup(wVersion, &wsaData);
	// WSAStartup(0x0202, &wsaData);
	CString ip;
	ip_edit.GetWindowText(ip);//取得伺服器的IP地址
	server_addr.sin_addr.s_addr = inet_addr(ip);
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(5150);
	if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
	{
		edit1.ReplaceSel("create socket error\r\n");
	}
	if (connect(sock, (struct sockaddr *) &server_addr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
	{
		edit1.ReplaceSel("連線失敗\r\n");
	}
	else
	{
		edit1.ReplaceSel("連線成功\r\n");
		AfxBeginThread(&recv_thd, 0);
		btnconn.EnableWindow(FALSE);//按鈕變灰
	}
	// TODO: 在此新增控制元件通知處理程式程式碼
}

4,新增顯示資料函式
void CcFileDlg::update(CString s)
{
	edit1.ReplaceSel(s + "\r\n");
}

5,新增全域性的執行緒函式用於接收資料
UINT recv_thd(LPVOID p)
{
	int res;
	char msg[1024];
	CString s;
	CcFileDlg * dlg = (CcFileDlg *)AfxGetApp()->GetMainWnd();
	dlg->update("連線成功");

	while (1)
	{
		if ((res = recv(sock, msg, 1024, 0)) == -1)
		{
			dlg->update("失去連線");
			break;
		}
		else
		{
			msg[res] = '\0';
			dlg->update("server:" + CString(msg));
		}
	}

	//closesocket(sock);
	return 0;
}

程式執行截圖: