基于winsocket的框体Server和Client
2014-07-17 18:44
405 查看
前面学了一点Winsock的知识,会编写简单的Server和Client,现在就想通过VS2008编写框体的Server和Client,而不是在控制台上的操作了,毕竟学编程就是要多加练习,在实践中发现不懂的地方,然后解决,然后再发现……
当然,作为一个刚接触Winsock的新手,大部分知识都来自于网上的资料,包括接下来的代码也是借鉴。。。
- 第一步利用VS2008创建一个Windows窗体应用程序chatServer(过程略);
- 设计你的窗体,简单的设计了一个窗体
注意,每一个组件都需要有唯一的Name,在设置好组件的属性后,可以双击这个组件,则会自动生成对应的动作函数; - 在Form1.h中写入如下代码,注意里面很多的函数时根据组件Name来命名的,所以copy时需要注意这一点;
#pragma once namespace chatServer { using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; using namespace System::Threading; using namespace System::Text; using namespace System::Net; using namespace System::Net::Sockets; using namespace System::IO; /// <summary> /// Form1 摘要 /// /// 警告: 如果更改此类的名称,则需要更改 /// 与此类所依赖的所有 .resx 文件关联的托管资源编译器工具的 /// “资源文件名”属性。否则, /// 设计器将不能与此窗体的关联 /// 本地化资源正确交互。 /// </summary> public ref class Form1 : public System::Windows::Forms::Form { Socket^ mySocket; Socket^ tempSocket; Thread^ myThread; int port; String^ host; public: Form1(void) { InitializeComponent(); // //TODO: 在此处添加构造函数代码 // } protected: /// <summary> /// 清理所有正在使用的资源。 /// </summary> ~Form1() { if (components) { delete components; } } private: System::Windows::Forms::TextBox^ IPBox; private: System::Windows::Forms::Label^ IP; private: System::Windows::Forms::TextBox^ ShowBox; private: System::Windows::Forms::TextBox^ InputBox; private: System::Windows::Forms::Label^ InputLabel; private: System::Windows::Forms::Button^ SendButton; private: System::Windows::Forms::Button^ ExitButton; public : String^ m_ShowText; public : String^ m_IPShowText; protected: private: /// <summary> /// 必需的设计器变量。 /// </summary> System::ComponentModel::Container ^components; #pragma region Windows Form Designer generated code /// <summary> /// 设计器支持所需的方法 - 不要 /// 使用代码编辑器修改此方法的内容。 /// </summary> void InitializeComponent(void) { this->IPBox = (gcnew System::Windows::Forms::TextBox()); this->IP = (gcnew System::Windows::Forms::Label()); this->ShowBox = (gcnew System::Windows::Forms::TextBox()); this->InputBox = (gcnew System::Windows::Forms::TextBox()); this->InputLabel = (gcnew System::Windows::Forms::Label()); this->SendButton = (gcnew System::Windows::Forms::Button()); this->ExitButton = (gcnew System::Windows::Forms::Button()); this->SuspendLayout(); // // IPBox // this->IPBox->Location = System::Drawing::Point(12, 21); this->IPBox->Name = L"IPBox"; this->IPBox->Size = System::Drawing::Size(181, 21); this->IPBox->TabIndex = 0; this->IPBox->TextChanged += gcnew System::EventHandler(this, &Form1::IPBox_TextChanged); // // IP // this->IP->AutoSize = true; this->IP->BackColor = System::Drawing::SystemColors::InactiveCaption; this->IP->Font = (gcnew System::Drawing::Font(L"宋体", 21.75F, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, static_cast<System::Byte>(134))); this->IP->Location = System::Drawing::Point(199, 13); this->IP->Name = L"IP"; this->IP->Size = System::Drawing::Size(178, 29); this->IP->TabIndex = 1; this->IP->Text = L"IP and Port"; this->IP->Click += gcnew System::EventHandler(this, &Form1::IP_Click); // // ShowBox // this->ShowBox->Location = System::Drawing::Point(12, 48); this->ShowBox->Multiline = true; this->ShowBox->Name = L"ShowBox"; this->ShowBox->ScrollBars = System::Windows::Forms::ScrollBars::Vertical; this->ShowBox->Size = System::Drawing::Size(365, 224); this->ShowBox->TabIndex = 2; this->ShowBox->TextChanged += gcnew System::EventHandler(this, &Form1::ShowBox_TextChanged); // // InputBox // this->InputBox->Location = System::Drawing::Point(12, 301); this->InputBox->Name = L"InputBox"; this->InputBox->ScrollBars = System::Windows::Forms::ScrollBars::Vertical; this->InputBox->Size = System::Drawing::Size(364, 21); this->InputBox->TabIndex = 3; this->InputBox->TextChanged += gcnew System::EventHandler(this, &Form1::InputBox_TextChanged); // // InputLabel // this->InputLabel->AutoSize = true; this->InputLabel->Location = System::Drawing::Point(12, 279); this->InputLabel->Name = L"InputLabel"; this->InputLabel->Size = System::Drawing::Size(113, 12); this->InputLabel->TabIndex = 4; this->InputLabel->Text = L"输入你要发送的信息"; this->InputLabel->Click += gcnew System::EventHandler(this, &Form1::InputLabel_Click); // // SendButton // this->SendButton->Location = System::Drawing::Point(34, 329); this->SendButton->Name = L"SendButton"; this->SendButton->Size = System::Drawing::Size(75, 23); this->SendButton->TabIndex = 5; this->SendButton->Text = L"发送"; this->SendButton->UseVisualStyleBackColor = true; this->SendButton->Click += gcnew System::EventHandler(this, &Form1::SendButton_Click); // // ExitButton // this->ExitButton->Location = System::Drawing::Point(296, 329); this->ExitButton->Name = L"ExitButton"; this->ExitButton->Size = System::Drawing::Size(75, 23); this->ExitButton->TabIndex = 6; this->ExitButton->Text = L"退出"; this->ExitButton->UseVisualStyleBackColor = true; this->ExitButton->Click += gcnew System::EventHandler(this, &Form1::ExitButton_Click); // // Form1 // this->AutoScaleDimensions = System::Drawing::SizeF(6, 12); this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font; this->ClientSize = System::Drawing::Size(425, 367); this->Controls->Add(this->ExitButton); this->Controls->Add(this->SendButton); this->Controls->Add(this->InputLabel); this->Controls->Add(this->InputBox); this->Controls->Add(this->ShowBox); this->Controls->Add(this->IP); this->Controls->Add(this->IPBox); this->Name = L"Form1"; this->Text = L"聊天---服务端"; this->Load += gcnew System::EventHandler(this, &Form1::Form1_Load); this->ResumeLayout(false); this->PerformLayout(); } #pragma endregion delegate void UpdateShowBox_Invoke(); void UpdateShowBox() { ShowBox->AppendText(m_ShowText);//在后面追加显示新的内容 } delegate void UpdateIPShowBox_Invoke(); void UpdateIPShowBox() { IPBox->AppendText(m_IPShowText); } void DoWork() { port = 2020;//设置端口号 host = "1.1.1.1"; //设置服务器地址,这里需要你本机的ip IPAddress^ ip = IPAddress::Parse(host); IPEndPoint^ ipe = gcnew IPEndPoint(ip,port); mySocket = gcnew Socket(AddressFamily::InterNetwork,SocketType::Stream,ProtocolType::Tcp);//创建一个socket类 mySocket->Bind(ipe);//绑定端口 m_IPShowText = host+" // "+port; this->Invoke(gcnew UpdateIPShowBox_Invoke(this,&Form1::UpdateIPShowBox));//显示IP和端口号 mySocket->Listen(0);//开始监听 tempSocket = mySocket->Accept();//为新建连接创建新的Socket //连接上后进行死循环,避免断开连接 while(1){ try{ String^ recvStr = ""; array<Byte>^ recvBytes = gcnew array<Byte>(1024); int bytes; bytes = tempSocket->Receive(recvBytes,recvBytes->Length,SocketFlags::None); //从客户端接收信息 recvStr = Encoding::Default->GetString(recvBytes,0,bytes); //转换数据为字符串 m_ShowText = "\r\n"+"Client 说:"+"\r\n"+recvStr+"\r\n"; //加上换行符把客户端传来的信息显示出来 this->Invoke(gcnew UpdateShowBox_Invoke(this,&Form1::UpdateShowBox)); } catch(EndOfStreamException^ e) { } catch(IOException^ e) { MessageBox::Show("I/O error"); } } } private: System::Void label1_Click(System::Object^ sender, System::EventArgs^ e) { } private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) { myThread = gcnew Thread(gcnew ThreadStart(this,&Form1::DoWork)); //创建一个线程 myThread->IsBackground = false; myThread->Start(); } private: System::Void SendButton_Click(System::Object^ sender, System::EventArgs^ e) { String^ sendStr = InputBox->Text; if(sendStr->Length > 0) { m_ShowText = "\r\n"+"我说:"+"\r\n"+sendStr+"\r\n"; //加上换行符 this->Invoke(gcnew UpdateShowBox_Invoke(this,&Form1::UpdateShowBox)); //本窗口显示发出去的内容 array<Byte>^ bs = Encoding::Default->GetBytes(sendStr); //将字符串转为二进制,支持中英文传输 tempSocket->Send(bs,bs->Length,SocketFlags::None); //把当前的聊天内容发送给客户端 InputBox->Text = ""; } } private: System::Void ExitButton_Click(System::Object^ sender, System::EventArgs^ e) { tempSocket->Close(); mySocket->Close(); myThread->Abort(); Application::Exit(); } private: System::Void IP_Click(System::Object^ sender, System::EventArgs^ e) { } private: System::Void InputLabel_Click(System::Object^ sender, System::EventArgs^ e) { } private: System::Void ShowBox_TextChanged(System::Object^ sender, System::EventArgs^ e) { } private: System::Void IPBox_TextChanged(System::Object^ sender, System::EventArgs^ e) { } private: System::Void InputBox_TextChanged(System::Object^ sender, System::EventArgs^ e) { } }; }
- 在chatServer中加入这一行代码:using namespace System::Threading;到此Server就基本完成了。。
- 仿照这样的方法完成Client端
- chatClient过程中Form1.h的代码
#pragma once namespace chatClient { using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; using namespace System::Threading; using namespace System::Text; using namespace System::Net; using namespace System::Net::Sockets; using namespace System::IO; /// <summary> /// Form1 摘要 /// /// 警告: 如果更改此类的名称,则需要更改 /// 与此类所依赖的所有 .resx 文件关联的托管资源编译器工具的 /// “资源文件名”属性。否则, /// 设计器将不能与此窗体的关联 /// 本地化资源正确交互。 /// </summary> public ref class Form1 : public System::Windows::Forms::Form { Socket^ mySocket; Socket^ tempSocket; Thread^ myThread; int port; String^ host; public: Form1(void) { InitializeComponent(); // //TODO: 在此处添加构造函数代码 // } protected: /// <summary> /// 清理所有正在使用的资源。 /// </summary> ~Form1() { if (components) { delete components; } } private: System::Windows::Forms::TextBox^ IPShowBox; protected: private: System::Windows::Forms::TextBox^ showBox; protected: private: System::Windows::Forms::Label^ label1; private: System::Windows::Forms::Label^ InputLabel; private: System::Windows::Forms::TextBox^ InputBox; private: System::Windows::Forms::Button^ SendButton; private: System::Windows::Forms::Button^ exitButton; public : String^ m_ShowText; public : String^ m_IPShowText; private: /// <summary> /// 必需的设计器变量。 /// </summary> System::ComponentModel::Container ^components; #pragma region Windows Form Designer generated code /// <summary> /// 设计器支持所需的方法 - 不要 /// 使用代码编辑器修改此方法的内容。 /// </summary> void InitializeComponent(void) { this->IPShowBox = (gcnew System::Windows::Forms::TextBox()); this->showBox = (gcnew System::Windows::Forms::TextBox()); this->label1 = (gcnew System::Windows::Forms::Label()); this->InputLabel = (gcnew System::Windows::Forms::Label()); this->InputBox = (gcnew System::Windows::Forms::TextBox()); this->SendButton = (gcnew System::Windows::Forms::Button()); this->exitButton = (gcnew System::Windows::Forms::Button()); this->SuspendLayout(); // // IPShowBox // this->IPShowBox->Location = System::Drawing::Point(32, 23); this->IPShowBox->Multiline = true; this->IPShowBox->Name = L"IPShowBox"; this->IPShowBox->Size = System::Drawing::Size(226, 30); this->IPShowBox->TabIndex = 0; this->IPShowBox->TextChanged += gcnew System::EventHandler(this, &Form1::IPShowBox_TextChanged); // // showBox // this->showBox->Location = System::Drawing::Point(32, 59); this->showBox->Multiline = true; this->showBox->Name = L"showBox"; this->showBox->ScrollBars = System::Windows::Forms::ScrollBars::Vertical; this->showBox->Size = System::Drawing::Size(425, 208); this->showBox->TabIndex = 1; this->showBox->TextChanged += gcnew System::EventHandler(this, &Form1::showBox_TextChanged); // // label1 // this->label1->AutoSize = true; this->label1->Font = (gcnew System::Drawing::Font(L"宋体", 18, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, static_cast<System::Byte>(134))); this->label1->Location = System::Drawing::Point(264, 23); this->label1->Name = L"label1"; this->label1->Size = System::Drawing::Size(142, 24); this->label1->TabIndex = 2; this->label1->Text = L"IP and Port\r\n"; // // InputLabel // this->InputLabel->AutoSize = true; this->InputLabel->Location = System::Drawing::Point(32, 274); this->InputLabel->Name = L"InputLabel"; this->InputLabel->Size = System::Drawing::Size(53, 12); this->InputLabel->TabIndex = 3; this->InputLabel->Text = L"输入信息"; // // InputBox // this->InputBox->Location = System::Drawing::Point(34, 290); this->InputBox->Name = L"InputBox"; this->InputBox->Size = System::Drawing::Size(302, 21); this->InputBox->TabIndex = 4; this->InputBox->TextChanged += gcnew System::EventHandler(this, &Form1::InputBox_TextChanged); // // SendButton // this->SendButton->Location = System::Drawing::Point(43, 317); this->SendButton->Name = L"SendButton"; this->SendButton->Size = System::Drawing::Size(75, 23); this->SendButton->TabIndex = 5; this->SendButton->Text = L"发送"; this->SendButton->UseVisualStyleBackColor = true; this->SendButton->Click += gcnew System::EventHandler(this, &Form1::SendButton_Click); // // exitButton // this->exitButton->Location = System::Drawing::Point(318, 317); this->exitButton->Name = L"exitButton"; this->exitButton->Size = System::Drawing::Size(75, 23); this->exitButton->TabIndex = 6; this->exitButton->Text = L"退出"; this->exitButton->UseVisualStyleBackColor = true; this->exitButton->Click += gcnew System::EventHandler(this, &Form1::exitButton_Click); // // Form1 // this->AutoScaleDimensions = System::Drawing::SizeF(6, 12); this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font; this->ClientSize = System::Drawing::Size(469, 350); this->Controls->Add(this->exitButton); this->Controls->Add(this->SendButton); this->Controls->Add(this->InputBox); this->Controls->Add(this->InputLabel); this->Controls->Add(this->label1); this->Controls->Add(this->showBox); this->Controls->Add(this->IPShowBox); this->Name = L"Form1"; this->Text = L"聊天--客户端"; this->Load += gcnew System::EventHandler(this, &Form1::Form1_Load); this->ResumeLayout(false); this->PerformLayout(); } #pragma endregion delegate void UpdateShowBox_Invoke(); void UpdateShowBox() { showBox->AppendText(m_ShowText);//在后面追加显示新的内容 } delegate void UpdateIPShowBox_Invoke(); void UpdateIPShowBox() { IPShowBox->AppendText(m_IPShowText); } void DoWork() { port = 2020;//设置端口号 host = "1.1.1.1";//设置服务器地址 IPAddress^ ip = IPAddress::Parse(host); IPEndPoint^ ipe = gcnew IPEndPoint(ip,port); mySocket = gcnew Socket(AddressFamily::InterNetwork,SocketType::Stream,ProtocolType::Tcp);//创建一个socket类 mySocket->Connect(ipe); m_IPShowText = host+" // "+port; this->Invoke(gcnew UpdateIPShowBox_Invoke(this,&Form1::UpdateIPShowBox));//显示IP和端口号 //连接上后进行死循环,避免断开连接 while(1){ try{ String^ recvStr = ""; array<Byte>^ recvBytes = gcnew array<Byte>(1024); int bytes; bytes = mySocket->Receive(recvBytes,recvBytes->Length,SocketFlags::None); //从客户端接收信息 recvStr = Encoding::Default->GetString(recvBytes,0,bytes); //转换数据为字符串 m_ShowText = "\r\n"+"Server 说:"+"\r\n"+recvStr+"\r\n"; //加上换行符把客户端传来的信息显示出来 this->Invoke(gcnew UpdateShowBox_Invoke(this,&Form1::UpdateShowBox)); } catch(EndOfStreamException^ e) { } catch(IOException^ e) { MessageBox::Show("I/O error"); } } } private: System::Void exitButton_Click(System::Object^ sender, System::EventArgs^ e) { mySocket->Close(); myThread->Abort(); Application::Exit(); } private: System::Void SendButton_Click(System::Object^ sender, System::EventArgs^ e) { String^ sendStr = InputBox->Text; if(sendStr->Length > 0) { m_ShowText = "\r\n"+"我说:"+"\r\n"+sendStr+"\r\n"; //加上换行符 this->Invoke(gcnew UpdateShowBox_Invoke(this,&Form1::UpdateShowBox)); //本窗口显示发出去的内容 array<Byte>^ bs = Encoding::Default->GetBytes(sendStr); //将字符串转为二进制,支持中英文传输 mySocket->Send(bs,bs->Length,SocketFlags::None); //把当前的聊天内容发送给客户端 InputBox->Text = ""; } } private: System::Void InputBox_TextChanged(System::Object^ sender, System::EventArgs^ e) { } private: System::Void showBox_TextChanged(System::Object^ sender, System::EventArgs^ e) { } private: System::Void IPShowBox_TextChanged(System::Object^ sender, System::EventArgs^ e) { } private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) { myThread = gcnew Thread(gcnew ThreadStart(this,&Form1::DoWork)); //创建一个线程 myThread->IsBackground = true; myThread->Start(); } }; }
- 同样需要在chatClient中加入using namespace System::Threading;
- 接下来执行,先打开Server,在打开Client
- 结果是:
相关文章推荐
- 基于Linux的SOCKET编程之TCP半双工Client-Server聊天程序
- 基于Linux的SOCKET编程之TCP半双工Client-Server聊天程序
- 基于WinSocket的单线程Server的实现
- [Socket]基于C++的纯面向对象的通用高性能大并发TCP-SERVER/CLIENT开发
- [Socket]基于C++的纯面向对象的通用高性能大并发TCP-SERVER/CLIENT开发框架
- 基于Linux的Socket编程之TCP全双工Server-Client聊天程序
- 基于WinSocket的单线程Client的实现
- JavaSE socket 基于UDP Server/Client的实现
- 基于Linux的Socket编程之TCP全双工Server-Client聊天程序
- Winsocket UDP Client and Server Examples
- Linux网络编程socket的简单应用(基于server和client 的tcp)
- Winsocket Server/Client 基本配置
- 基于C++的纯面向对象的通用高性能大并发TCP-SERVER/CLIENT开发框架实践系列之前言篇
- 基于NIO的Client/Server程序实践
- Socket的Server-Client模型的程序
- 译文:异步Socket服务器与客户端(An Asynchronous Socket Server and Client) (转)
- linux c socket server client 实例
- [转载]异步Socket服务器与客户端(An Asynchronous Socket Server and Client)
- 代码客:G-Socket(IOCP) 1.0(Server/Client)例程源码+Server体验程序+强大的压力测试工具
- Socket编程:得到本地Server主机IP和对方Client主机IP