Winsock网络编程

1.网络编程的基本步骤

在网络编程中,一般分Server和Client端两种。
其中Server端的步骤基本如下:
1. 初始化Winsock
2. 创建socket
3. 绑定 socket
4. 在socket上监听客户端
5. 接受来自client的连接
6. 接受和发送数据
7. 断开连接

Client端的步骤基本如下:
1. 初始化Winsock
2. 创建socket
3. 连接到Server
4. 发送和接受数据
5. 断开连接

2.Winsock加载和卸载

要使用Windows Socket API进行编程,一般在程序开始要用WSAStartup进行初始化动态库,在程序结束要用WSACleanup进行卸载Winsock动态库。
包括的头文件是:

#include <WinSock2.h>

要加载的库是:

#pragma comment(lib,"Ws2_32.lib")

WSAStartup函数:初始化Winsock动态库

int WSAStartup(
  _In_  WORD      wVersionRequested,
  _Out_ LPWSADATA lpWSAData
);

其中wVersionRequested是指调用者能使用的Windows Sockets指定的最高版本号;
lpWSAData是要接收Windows套接字实现的详细信息的WSAData数据结构体指针。
返回值:
如果成功,返回0,否则返回错误码。

3.代码实现

3.1 Server端代码

// ServerCmd.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <WinSock2.h>
#include <WS2tcpip.h>

#pragma comment(lib,"Ws2_32.lib")

int main()
{
    WSADATA wsaData;
    SOCKET serverSocket;

    int nResult = 0;

    //初始化动态库
    nResult = WSAStartup(MAKEWORD(2, 2), &wsaData);

    //创建WSASocket
    serverSocket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);

    IN_ADDR addr;
    InetPton(AF_INET, L"192.168.165.100", (void*)&addr);

    SOCKADDR_IN addrIn;
    addrIn.sin_family = AF_INET;
    addrIn.sin_addr.S_un.S_addr = addr.S_un.S_addr;
    addrIn.sin_port = htons(4303);

    //绑定socket
    //The bind function associates a local address with a socket.
    nResult = bind(serverSocket, (SOCKADDR*)&addrIn, sizeof(SOCKADDR_IN));
    if (nResult == SOCKET_ERROR) {
        printf("errorCode = %d\n", WSAGetLastError());
        closesocket(serverSocket);
        WSACleanup();
        return 1;
    }
    else {
        printf("bind success!\n");
    }

    //监听
    //The listen function places a socket in a state in which it is listening for an incoming connection.
    //If no error occurs, listen returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.
    nResult = listen(serverSocket, 100);
    if (nResult != 0) {
        printf("errorCode = %d\n", WSAGetLastError());
        closesocket(serverSocket);
        WSACleanup();
        return 1;
    }
    else {
        printf("listen success!\n");
    }   

    SOCKET clientSocket;
    char recvBuf[100];
    memset(recvBuf, 0, 100 * sizeof(char));

    printf("Start Server:\n");
    //接收客户端的连接
    //The accept function permits an incoming connection attempt on a socket.
    clientSocket = accept(serverSocket, NULL, NULL);
    if (clientSocket == INVALID_SOCKET) {
        printf("errorCode = %d\n", WSAGetLastError());
        closesocket(serverSocket);
        WSACleanup();
        return 1;
    }
    else {
        printf("accept success.\n");
    }

    while (1) {
        //接收客户端发送的消息
        nResult = recv(clientSocket, recvBuf, 100, 0);
        if (nResult > 0) {
            printf("recv msg : %s \n", recvBuf);
        }   
    }

    //关闭socket
    closesocket(serverSocket);

    WSACleanup();

    system("pause");

    return 0;
}

3.2 Client端代码

// ClientCmd.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <WinSock2.h>
#include <WS2tcpip.h>

#pragma comment(lib,"Ws2_32.lib")

int main()
{
    WSADATA wsaData = { 0 };
    int nResult = 0;
    char sendBuf[] = "This is a test message.";

    SOCKET socket;

    socket = INVALID_SOCKET;

    //If successful, the WSAStartup function returns zero. 
    //Otherwise, it returns one of the error codes listed below.
    nResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (nResult != 0) {
        printf("errorCode = %d\n",WSAGetLastError());
        WSACleanup();
        return 1;
    }

    //创建WSASocket
    socket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
    if (socket == INVALID_SOCKET) {
        printf("errorCode = %d\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }

    //SOCKADDR_IN addr;
    //addr.sin_family = AF_INET;
    //addr.sin_addr.S_un.S_addr = inet_addr("192.168.165.100");
    //addr.sin_port = htons(4303);

    IN_ADDR addr;
    InetPton(AF_INET, L"192.168.165.100", (void*)&addr);

    SOCKADDR_IN addrIn;
    addrIn.sin_family = AF_INET;
    addrIn.sin_addr.S_un.S_addr = addr.S_un.S_addr;
    addrIn.sin_port = htons(4303);

    //连接服务器
    //If no error occurs, connect returns zero. 
    //Otherwise, it returns SOCKET_ERROR, 
    //and a specific error code can be retrieved by calling WSAGetLastError.
    //connect(socket, (const SOCKADDR*)&address, sizeof(SOCKADDR));
    nResult = connect(socket, (SOCKADDR*)&addrIn, sizeof(SOCKADDR_IN));

    if (nResult == SOCKET_ERROR) {
        printf("errorCode = %d\n", WSAGetLastError());
        closesocket(socket);
        WSACleanup();
        return 1;
    }

    //发送数据
    nResult = send(socket, sendBuf, (int)strlen(sendBuf), SOCK_STREAM);
    if (nResult == SOCKET_ERROR) {
        printf("errorCode = %d\n", WSAGetLastError());
        closesocket(socket);
        WSACleanup();
        return 1;
    }

    //关闭socket
    closesocket(socket);

    WSACleanup();

    system("pause");

    return 0;
}

3.3 服务器端运行结果

bind success!
listen success!
Start Server:
accept success.
recv msg : This is a test message
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

祝云飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值