windows socket 学习写的

来源:互联网 发布:桥接模式java类图 编辑:程序博客网 时间:2024/06/07 12:50
必须先启动一个选择服务器再 启动一个选择客服端  然后不能两个同时选择接受。。。。真吭人是吧没办法 啊
#pragma once#define  MSG_SIZE 100//消息的最大值#include <iostream>#include <string>#include <vector>#include <WinSock2.h>#pragma comment(lib,"wsock32.lib")using namespace std;class YdcSocket{public:YdcSocket(){}void InitYdcSocket(bool isServer){//初始化套接字动态库if ( WSAStartup(MAKEWORD(2,2),&wsd)!=0 ){ErrorMsg.push_back("WSAStartup failed!");}if (isServer){//创建套接字sServer = socket(AF_INET,SOCK_STREAM ,IPPROTO_TCP);if (INVALID_SOCKET == sServer){ErrorMsg.push_back("socket failed!");}//服务器套接字地址addrServ.sin_family = AF_INET;cout<<"正在启动服务器"<<endl;addrServ.sin_port = htons(4999);addrServ.sin_addr.s_addr = INADDR_ANY;Bind();Listen();Accept();}else{//创建套接字sClient = socket(AF_INET,SOCK_STREAM ,IPPROTO_TCP);if (INVALID_SOCKET == sServer){ErrorMsg.push_back("socket failed!");}//服务器套接字地址addrServ.sin_family = AF_INET;cout<<"正在启动客服端"<<endl;addrServ.sin_port = htons((short)4999);addrServ.sin_addr.s_addr = inet_addr("127.0.0.1");Connect();}}~YdcSocket(void){}public:void strat(){while (1){cin.clear();int n = 0;cout<<"1 发送 2 接收 其他 查看错误日志"<<endl;cin>>n;switch (n){case 1://发送cout<<"请输入你要发送的消息"<<endl;cin>>msg;Send();break;case 2://接收msg = "";cout<<"你将接收消息"<<endl;Recv();cout<<"你接受到的消息是:"<<msg<<endl;break;default:ShowError();break;}}}void Recv(){ZeroMemory(buf,MSG_SIZE);if (SOCKET_ERROR == recv(sClient,buf,MSG_SIZE,0)){ErrorMsg.push_back("非法关闭 failed!");closesocket(sServer);closesocket(sClient);WSACleanup();}else if (retVal == 0){ErrorMsg.push_back("正常关闭 failed!");closesocket(sServer);closesocket(sClient);WSACleanup();}msg = buf;}void Send(){cout<<strlen(msg.c_str());if (SOCKET_ERROR == send(sClient,msg.c_str(),strlen(msg.c_str()),0)){ErrorMsg.push_back("send failed!");closesocket(sClient);WSACleanup();}}private:vector<string>ErrorMsg;//错误消息stringmsg;//消息char buf[MSG_SIZE];//发送的消息WSADATAwsd;//WSADATA变量SOCKETsServer;//服务器套接字SOCKETsClient;//客服端套接字SOCKADDR_INaddrServ;//服务器地址intretVal;//还回值private:void Bind(){if (SOCKET_ERROR == ::bind(sServer,(LPSOCKADDR)&addrServ,sizeof(SOCKADDR_IN))){ErrorMsg.push_back("1 failed!");::closesocket(sServer);WSACleanup();}}void Listen(){if (::listen(sServer, SOMAXCONN) == SOCKET_ERROR){ErrorMsg.push_back("2 failed!");::closesocket(sServer);WSACleanup();}}void Accept(){cout<<"等待客服"<<endl;int m_addrLen = sizeof(addrServ);sClient = ::accept(sServer,(SOCKADDR*)&addrServ, &m_addrLen);if (sClient == INVALID_SOCKET){ErrorMsg.push_back("3 failed!");::closesocket(sClient);WSACleanup();}}void Connect(){//这里需要if (SOCKET_ERROR == ::connect(sClient, (LPSOCKADDR)&addrServ, sizeof(SOCKADDR_IN) ) ){ErrorMsg.push_back("4 failed!!");::closesocket(sClient);WSACleanup();}}void ShowError(){for (int i =0 ; i < ErrorMsg.size() ; i++){cout<<ErrorMsg.at(i)<<endl;}}};
// Socket类.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include "YdcSocket.h"int _tmain(int argc, _TCHAR* argv[]){YdcSocket y;int n;cout<<"请输入 1 选择为服务器  0 为客服端"<<endl;cin>>n;y.InitYdcSocket(n);y.strat();system("pause");return 0;}


然后呢我就想 要是能否有多人 随意点就好了 想发就发想收就收 那该多好 啊 。。

就想到了 多线程  结果发现  这个 是 阻塞的 (好乱的 )

就找到了

winsock I/O模型

。。。简单的 就是select 模型:了 呵呵 再写写