zoukankan      html  css  js  c++  java
  • WinSock入门(一)

    最基本的Winsock的程序。

    本来应该作为博客的代码Wiki部分进行保存,而不是一篇博文的。无奈自建博客的计划迟迟没有开动的迹象,先忍忍。

    这两个文件完成了最简单的Winsock的例子:服务器端进行侦听,客户端发起连接,发送数据,服务器端收到数据后进行反馈。

    下面是客户端的代码文件:

    // ClientProcess.cpp
    #include "StdAfx.h"
    #include "ClientProcess.h"
    
    #include <iostream>
    #include <WinSock2.h>
    
    #pragma comment(lib, "Wsock32")
    
    using namespace std;
     
    #define CHECK_SOCK_ERROR(funName, cond)                        \
        do {                                                       \
            if (cond)                                              \
            {                                                      \
                cout<<#funName" error: "<<WSAGetLastError()<<endl; \
                return;                                            \
            }                                                      \
        }while(0)
    
    
    void PrepairWinsock(){
        WSADATA wsaData;
        WORD    sockVersion = MAKEWORD(2, 0);
        if (0 != WSAStartup(sockVersion, &wsaData))
        {
            cout<<"WSAStartup Error!"<<endl;
        }
    }
    
    void CleanWinsock(){
        WSACleanup();
    }
    
    void SentData(){
        SOCKET clientSocket = NULL;
    
        // type 0 is TCP/IP
        clientSocket = socket(AF_INET, SOCK_STREAM, 0);
    
        int serverPort = 4444;
        SOCKADDR_IN serverSockAddr;
        serverSockAddr.sin_family           = AF_INET;
        serverSockAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); // 服务器端是同一主机
        serverSockAddr.sin_port             = htons(serverPort);      // 端口为1024到5000之间的任意值
    
        int ret = connect(clientSocket, (LPSOCKADDR)&serverSockAddr, sizeof(serverSockAddr));
        CHECK_SOCK_ERROR(connect, ret);
    
        char strSend[] = "test data!";
        ret = send(clientSocket, strSend, sizeof(strSend), 0);
        CHECK_SOCK_ERROR(send, SOCKET_ERROR == ret);
    
        int const BUFF_SIZE = 256;
        char buff[BUFF_SIZE] = {0};
        cout<<"Start recv"<<endl;
        ret = recv(clientSocket, buff, BUFF_SIZE, 0);
        CHECK_SOCK_ERROR(recv, SOCKET_ERROR == ret);
    
        cout<<"Recv Data: "<<buff<<endl;
        
        closesocket(clientSocket);
    }
    
    void SendDataByWinSock(){
        PrepairWinsock();
        SentData();
        CleanWinsock();
    }

    另一个是服务器端的代码:

    //ServerProcess.cpp
    #include "StdAfx.h"
    #include "ServerProcess.h"
    #include <iostream>
    #include <string>
    #include <WinSock2.h>
    
    #pragma comment(lib, "Wsock32")
    
    using namespace std;
    
    #define CHECK_SOCK_ERROR(funName, cond)                        \
        do {                                                       \
            if (cond)                                              \
            {                                                      \
                cout<<#funName" error: "<<WSAGetLastError()<<endl; \
                return;                                            \
            }                                                      \
        }while(0)
    
    void PrepairWinsock(){
        WSADATA wsaData;
        WORD    sockVersion = MAKEWORD(2, 0);
        if (0 != WSAStartup(sockVersion, &wsaData))
        {
            cout<<"WSAStartup Error!"<<endl;
        }
    }
    
    void CleanWinsock(){
        WSACleanup();
    }
    
    void WaitForData(){
        SOCKET serverSocket = NULL;
    
        // type 0 is TCP/IP
        serverSocket = socket(AF_INET, SOCK_STREAM, 0);
    
        int serverPort = 4444;
        SOCKADDR_IN serverSockAddr;
        serverSockAddr.sin_family           = AF_INET;
        serverSockAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
        serverSockAddr.sin_port             = htons(serverPort); // 端口为1024到5000之间的任意值
        
        cout<<"Start bind"<<endl;
        int ret = bind(serverSocket, (LPSOCKADDR)&serverSockAddr, sizeof(serverSockAddr));
        CHECK_SOCK_ERROR(bind, SOCKET_ERROR == ret);
    
        cout<<"Start listen"<<endl;
        ret = listen(serverSocket, 2);
        CHECK_SOCK_ERROR(listen, SOCKET_ERROR == ret);
    
        cout<<"Start accept"<<endl;
        // accept 会返回另一个socket,这个socket用于通信,而原来的
        // sockte继续进行侦听。
        SOCKET dataCommuSock = accept(serverSocket, NULL, NULL);
        CHECK_SOCK_ERROR(accept, INVALID_SOCKET == dataCommuSock);
    
        int const BUFF_SIZE = 256;
        char buff[BUFF_SIZE] = {0};
        cout<<"Start recv"<<endl;
        ret = recv(dataCommuSock, buff, BUFF_SIZE, 0);
        CHECK_SOCK_ERROR(recv, (0 == ret) || (SOCKET_ERROR == ret));
    
        string strRecv(buff);
        cout<<"recv message : "<<strRecv<<endl;
    
        strRecv += strRecv;
        send(dataCommuSock, strRecv.c_str(), strRecv.size(), 0);
        CHECK_SOCK_ERROR(send, SOCKET_ERROR == ret);
    
        cout<<"close socket"<<endl;
        closesocket(serverSocket);
        closesocket(dataCommuSock);
    }
    
    void GetDataByWinSock(){
        PrepairWinsock();
        WaitForData();
        CleanWinsock();
    }

    这里面的对socket的调用都是阻塞式的。

     

    ---- 总会有一个人需要你的分享~! 唐风: www.cnblogs.com/muxue ------
  • 相关阅读:
    SpringMVC传值、转发、重定向例子
    内存、指针操作函数
    文件、磁盘操作函数
    字符串、数组操作函数 Copy Concat Delete Insert High MidStr Pos SetLength StrPCopy TrimLeft
    Delphi代码模拟“显示桌面”的功能
    SQLite 入门教程(四)增删改查,有讲究
    NET Core
    Publisher/Subscriber 订阅-发布模式
    数据分片
    C#调用Java方法
  • 原文地址:https://www.cnblogs.com/muxue/p/2348444.html
Copyright © 2011-2022 走看看