1. 程式人生 > >網路聊天室(MFC程式設計)

網路聊天室(MFC程式設計)

本應用是一款簡單的模擬qq聊天應用.主要分為伺服器端與客戶端

伺服器select端:

客戶端client:

伺服器端程式碼如下:

select.cpp:

// select.cpp : 定義控制檯應用程式的入口點。//#include "stdafx.h"#include "dataHandle.h"#include#pragma comment(lib, "ws2_32")

void SockInit();

int _tmain(int argc, _TCHAR* argv[])

{

SockInit();

SOCKET lisSock = socket(AF_INET, SOCK_STREAM, 0);

sockaddr_in addr;

addr.sin_family = AF_INET;

addr.sin_port = htons(8090);

addr.sin_addr.S_un.S_addr = ADDR_ANY;

bind(lisSock, (sockaddr*)&addr, sizeof(sockaddr));

listen(lisSock, 5);

fd_set fds;

FD_ZERO(&fds);

FD_SET(lisSock, &fds);  //將監聽套接字加入陣列中

timeval timeout;

timeout.tv_sec = 5;

timeout.tv_usec = 0;

while (1)

{

fd_set tmSet = fds;  //臨時陣列

//移除掉沒有事件發生的套接字

// SELECT 在程式設計的過程中,經常會遇到許多阻塞的函式,

//好像read和網路程式設計時使用的recv, recvfrom函式都是阻塞的函式,

//當函式不能成功執行的時候,程式就會一直阻塞在這裡,無法執行下面的程式碼。

//這是就需要用到非阻塞的程式設計方式,使用select函式就可以實現非阻塞程式設計。

select(0, &tmSet, 0, 0, &timeout);

SOCKET s[5];

int j = 0;

//剩下的都是有事件發生的套接字

for (int i = 0; i < tmSet.fd_count; i++)

{

if (tmSet.fd_array[i] == lisSock) //如果是監聽監聽套接字

{

SOCKET cliSock = accept(lisSock, 0, 0);

printf("新連線.\n");

FD_SET(cliSock, &fds);  //將已連線的套接字加入陣列中

}

else

{

char recvBuf[1024] = { 0 };

int recvLen = recv(tmSet.fd_array[i], recvBuf, 1024, 0);

if (recvLen > 0)

{

//處理資料

HandleData(recvBuf,recvLen);

printf("%s\n",recvBuf);

}

else  //錯誤發生,或者客戶端斷開連線

{

printf("客戶已斷開\n");

FD_CLR(tmSet.fd_array[i], &fds);  //從陣列中移除已埠的客戶端

}

}

}

}

return 0;

}

void SockInit()

{

WORD wVersionRequested;

WSADATA wsaData;

int err;

wVersionRequested = MAKEWORD(2, 2);

err = WSAStartup(wVersionRequested, &wsaData);

if (err != 0) {

return;

}

if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)

{

WSACleanup();

return;

}

}

dataHandle.h 用於伺服器接收到不同型別訊息處理

#pragma once#include//處理收到的資料

bool HandleData(const char* recvData,int len);

dataHandle.cpp

#include "stdafx.h"

#include "dataHandle.h"

#include "netStruct.h"

//處理收到的資料

bool HandleData(const char* recvData,int len)

{

//printf("%s : %d", recvData, len);

short msgID = *(short*)recvData;

switch (msgID)

{

case TALKALL_MSGID:

{

//...給所有人的訊息

const MSG_TALKALL* takAll = (MSG_TALKALL*)recvData;

printf("群聊訊息: %s\n", takAll->Content);

}

break;

case TALKONE_MSGID:

{

//給某個人的訊息

const MSG_TALKONE* takOne = (MSG_TALKONE*)recvData;

printf("私聊訊息: %s : %s\n", takOne->userName, takOne->Content);

//takOne.useName

}

break;

case LOGIN_MSGID:

//登陸訊息

break;

//.........

case FILEINFO_MSGID:

{

const MSG_SENDFILEINFO *fileInfo = (MSG_SENDFILEINFO*)recvData;

printf("檔案路徑:%s ,檔案大小:%d\n", fileInfo->fileName, fileInfo->fileSize);

}

break;

case FILE_MSGID:

{

const MSG_SENDFILE *file = (MSG_SENDFILE*)recvData;

printf("檔案內容:%s\n", file->fileBuf);

}

break;

default:

break;

}

return true;

}

netStruct.h 傳輸的資訊結構體

#pragma once

#define TALKALL_MSGID 10001

#define TALKONE_MSGID 10002

#define LOGIN_MSGID 10003

#define SENDPIC_MSGID 10004

#define FILEINFO_MSGID 10005

#define FILE_MSGID 10006

//給所有人發的訊息

struct MSG_TALKALL

{

short msgID;

char Content[1024];

};

//給某人發的訊息

struct MSG_TALKONE

{

short msgID;

char userName[32];

char Content[1024];

};

struct MSG_SENDFILEINFO {

short msgID;

char fileName[256];

int fileSize;

};

struct MSG_SENDFILE {

short msgID;

int bufID;

short bufSize;

char fileBuf[1024];

};

客戶端中

client.cpp

BOOL CclientApp::InitInstance(){

// 如果一個執行在 Windows XP 上的應用程式清單指定要

// 使用 ComCtl32.dll 版本 6 或更高版本來啟用視覺化方式,

//則需要 InitCommonControlsEx()。  否則,將無法建立視窗。

INITCOMMONCONTROLSEX InitCtrls;

InitCtrls.dwSize = sizeof(InitCtrls);

// 將它設定為包括所有要在應用程式中使用的

// 公共控制元件類。

InitCtrls.dwICC = ICC_WIN95_CLASSES;

InitCommonControlsEx(&InitCtrls);

CWinApp::InitInstance();

AfxEnableControlContainer();

// 建立 shell 管理器,以防對話方塊包含

// 任何 shell 樹檢視控制元件或 shell 列表檢視控制元件。

CShellManager *pShellManager = new CShellManager;

// 啟用“Windows Native”視覺管理器,以便在 MFC 控制元件中啟用主題

CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));

// 標準初始化

// 如果未使用這些功能並希望減小

// 最終可執行檔案的大小,則應移除下列

// 不需要的特定初始化例程

// 更改用於儲存設定的登錄檔項

// TODO: 應適當修改該字串,

// 例如修改為公司或組織名

SetRegistryKey(_T("應用程式嚮導生成的本地應用程式"));

AfxSocketInit();//網路初始化

clientSock sock;

sock.Create();

bool conRet = sock.Connect(_T("127.0.0.1"), 8090);

if (conRet == false) {

int errCode = GetLastError();

CString err;

err.Format(_T("連線伺服器失敗 : %d,請重試!"), errCode);

MessageBox(0, err, _T("錯誤"), MB_OK);

return FALSE;

}

Login log;//登入介面

INT_PTR res = log.DoModal();

if (res == IDOK) {

CclientDlg dlg(sock,log.userName);//傳送資訊介面,將socket傳入對話方塊介面,以發信資訊

m_pMainWnd = &dlg;

INT_PTR nResponse = dlg.DoModal();

if (nResponse == IDOK)

{

// TODO: 在此放置處理何時用

//  “確定”來關閉對話方塊的程式碼

}

else if (nResponse == IDCANCEL)

{

// TODO: 在此放置處理何時用

//  “取消”來關閉對話方塊的程式碼

}

else if (nResponse == -1)

{

TRACE(traceAppMsg, 0, "警告: 對話方塊建立失敗,應用程式將意外終止。\n");

TRACE(traceAppMsg, 0, "警告: 如果您在對話方塊上使用 MFC 控制元件,則無法 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS。\n");

}

// 刪除上面建立的 shell 管理器。

if (pShellManager != NULL)

{

delete pShellManager;

}

#ifndef _AFXDLL

ControlBarCleanUp();

#endif

// 由於對話方塊已關閉,所以將返回 FALSE 以便退出應用程式,

//  而不是啟動應用程式的訊息泵。

}

客戶端登入介面:

在文字框輸入文字,併發送出去程式碼如下:

void CclientDlg::OnBnClickedOk()

{

// TODO: 在此新增控制元件通知處理程式程式碼

//CDialogEx::OnOK();

UpdateData();

if (content_send.IsEmpty()) {

MessageBox(_T("請填入訊息!"), _T("提示"), MB_OK);

return;

}

if (isSendFile == FALSE) {

/*

char *buff;

buff = (char *)content_send.GetBuffer(0);

m_sock.Send(buff, strlen(buff),0);//用多位元組來發送

content_send = _T("");//清空內容

*/

/*

MSG_TALKONE takone;

takone.msgID = TALKONE_MSGID;

strcpy_s(takone.userName, userName);

strcpy_s(takone.Content, content_send.GetBuffer(0));

m_sock.Send(&takone, sizeof(MSG_TALKONE));

*/

MSG_TALKALL takall;

takall.msgID = TALKALL_MSGID;

strcpy_s(takall.Content, content_send.GetBuffer(0));

m_sock.Send(&takall, sizeof(MSG_TALKALL));

content_send = _T("");//清空內容

UpdateData(0);

}

else//傳送檔案

{

CreateThread(0, 0,sendFileThread, this,0,0);//方法只能為全域性方法,不能為類方法

相關推薦

網路聊天(MFC程式設計)

本應用是一款簡單的模擬qq聊天應用.主要分為伺服器端與客戶端伺服器select端:客戶端client:伺服器端程式碼如下:select.cpp:// select.cpp : 定義控制檯應用程式的入口點。//#include "stdafx.h"#include "dataH

14 QT TCP網路程式設計網路聊天的實現

網路裝置:用於遠端的計算機間的通訊. 每個網路裝置都有一個ip地址. ip地址用於區分一個區域網內不同的計算機, ip地址在同一個區域網內不可以重複使用(如重複使用會兩個都連不了網), ip地址可由路由器動態分配,也可以手動指定. 網路掩碼用於指定所屬的區域

java實戰——網路聊天

因特網已經成為了人們交流的海洋,上網的使用者越來越多,更多的人願意使用網路來認識別人,瞭解別人,這就是當下諸如qq、微信等聊天工具火熱的原因。 我們雖然不能立馬就開發出來一個像上述兩個一樣功能強大的聊天室,但我們可以自己製作一個簡單的聊天室。 我們採用傳統的Client/Server結構,功

[原始碼和文件分享]基於java語言的C/S模式網路聊天軟體

一 需求分析 採用C/S模式,基於TCP協議程式設計的方式,使得各個使用者通過伺服器轉發實現聊天的功能 分為三大模組:客戶端模組、伺服器端模組和公共輔助類模組 客戶端模組的主要功能: 登陸功能:使用者可以註冊,然後選擇伺服器登入聊天室

Java NIO示例:多人網路聊天

一個多客戶端聊天室,支援多客戶端聊天,有如下功能: 功能1: 客戶端通過Java NIO連線到服務端,支援多客戶端的連線 功能2:客戶端初次連線時,服務端提示輸入暱稱,如果暱稱已經有人使用,提示重新輸入,如果暱稱唯一,則登入成功,之後傳送訊息都需要按照規定格式帶著

java socket 基於netty的網路聊天

Netty是一個Java的NIO客戶端服務端框架可以快速的開發網路應用程式,比如客戶端和服務端的協議,大大簡化了網路程式的開發過程。我們知道Netty的整體架構主要由3部分組成:緩衝(buffer)、通道(channel)、事件模型(event model)。所有的

boost asio非同步讀寫網路聊天【官方示例】

// // chat_message.hpp // ~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distri

基於linux的TCP網路聊天設計與實現

利用Linux實現基於TCP模式的網路聊天程式 主要完成的兩大組成部分為:伺服器和客戶端。 伺服器程式主要負責監聽客戶端發來的訊息。 客戶端需要登入到伺服器端才可以實現正常的聊天功能。該程式是利用程序以及共享記憶體來實現群傳送訊息的。 以下簡單分析一下

linux系統下一個基於TCP的網路聊天

本聊天室程式在Ubuntu下,採用C語言實現,結構為Client/Server結構; 服務端程式通過共享儲存區儲存聊天資料,併發送給每個連線的客戶端; 服務端程式和客戶端程式都是通過父子程序分別負責傳送和接收資料的,以避免資料衝撞; 需按以下格式呼叫客戶端程式:client

Java學習筆記之--------網路程式設計之Socket通訊----聊天實現

Socket通訊 網路上的兩個程式通過一個雙向的通訊連線實現資料的交換,這個連線的一端稱為一個socket。基於TCP/IP協議,建立穩定的點對點的通訊。 特點:實時、快速、安全性高、佔用系統資源多、效率低。 通常也稱作"套接字",套接字是一種程序間的資料交換機制。這些程序既可以在同一機

(二)網路程式設計聊天(2)

第五步:既然是聊天室,那麼僅僅只能一個使用者自己和自己聊天,顯然該該程式是有瑕疵的。那麼我們就需要支援多使用者同時線上聊天。這一步中,我們就需要用到多執行緒的概念。為什麼要用到多執行緒?執行緒可以通俗的理解為每有一個新運動員便多建造一條跑道,以便所有運動員可以經歷同樣的從頭到尾的全部過程。那如果放到

(二)網路程式設計聊天(1)

概述:通過網路程式設計來實現聊天室功能 第一步:建立服務端與客戶端並建立連線         服務端:         import java.io.IOException;     &n

python網路程式設計之udp的聊天

import socket def main(): #建立套接字 udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) udp_socket.bind(("192.168.227.129",7567

python-網路程式設計-模擬聊天

本文作者:黎智煊,叩丁狼高階講師。原創文章,轉載請註明出處。 udp應用:echo伺服器 模擬的是設定一個伺服器,一旦有客戶端傳送資料到服務端,服務端馬上響應訊息給客戶端,類似機器人自動回覆. 參考程式碼 #coding=utf-8 from socket

Python網路程式設計---實現聊天

寫一個聊天室 要求: 1.進入聊天室需要輸入姓名,姓名不能重複 2.有人進入聊天室會想其他人傳送通知,xxx 進入了聊天室 3.一個人發訊息,其他人會收到訊息 xxx 說:xxxx 4.某人退出聊天室,其他人也會收到通知 xxx 退出了聊天室 5.管理員喊話功能 -基於u

Python網路程式設計----實現簡單的多人聊天

還是用UDP,socket作為主體來實現,之前我們已經實現過單對單socket通訊,這次想實現群發功能 原理其實就是一臺伺服器在負責分配轉發資料,來達成廣播的效果,這些思路其實也差不多 但是多人聊天沒有這麼強的規整性,你可能沒等到A的訊息,就要去和B說話了,多執行緒就可以

JAVA_網路程式設計_TCP_Socket通訊_聊天_多人聊天/私聊_實現

Socket程式設計 連線(連線是通過輸入輸出流來傳送資料)   建立伺服器 package com.hp.tcp; import java.io.DataInputStream; import java.io.DataOutputStream; import

基於UDP的網路程式設計實現簡單聊天

import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.util.Scanner; pu

linux網路程式設計練習---聊天(TCP/IP實現)

為了更深刻的鍛鍊認識TCP/IP協議,加強自己對Linux系統的網路程式設計部分的編寫程式碼能力,編寫基於控制檯的聊天視窗,用本機既當伺服器又當客戶端,先開啟一個shell,執行伺服器程式,然後再開啟一個shell視窗,執行客戶端程式,顯示連線成功,開始聊天吧。不知道為什麼

網路程式設計概念。一個UDP構造的聊天

網路程式設計:利用網路將不同計算機資料進行交換 網路三要素: IP地址   +   埠 =Socket 協議 :UDP,TCP      inetAddress類的使用public class InetAddressDemo { public static void m