windows Socket编程教程之TCP服务端与客户端简单通信

首先感谢原作者**Timmiy**文章《windows Socket编程之TCP服务端与客户端》及原作者**woniu199166**《error C4996---解决方法》文章指导。
运行平台为VS 2017
出现C4996 错误加上#pragma warning(disable:4996)得以解决
服务器端:

#include <stdio.h>  
#include <winsock2.h> // 必须包含windwos.h之前
#include <Windows.h>

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

#define  PORT 6000
DWORD WINAPI clientProc(LPARAM lparam)
{
    SOCKET sockClient = (SOCKET)lparam;
    char buf[1024];
    while (TRUE)
    {
        memset(buf, 0, sizeof(buf));
        // 接收客户端的一条数据 
        int ret = recv(sockClient, buf, sizeof(buf), 0);
        //检查是否接收失败
        if (SOCKET_ERROR == ret)
        {
            printf("socket recv failed\n");
            closesocket(sockClient);
            return -1;
        }
        // 0 代表客户端主动断开连接
        if (ret == 0)
        {
            printf("client close connection\n");
            closesocket(sockClient);
            return -1;
        }
        // 发送数据
        ret = send(sockClient, buf, strlen(buf), 0);
        //检查是否发送失败
        if (SOCKET_ERROR == ret)
        {
            printf("socket send failed\n");
            closesocket(sockClient);
            return -1;
        }
    }
    closesocket(sockClient);
    return 0;
}
bool InitNetEnv()
{
    // 进行网络环境的初始化操作
    WSADATA wsa;
    if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
    {
        printf("WSAStartup failed\n");
        return false;
    }
    return true;
}
int main(int argc, char * argv[])
{
    if (!InitNetEnv())
    {
        return -1;
    }
    // 初始化完成,创建一个TCP的socket
    SOCKET sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    //检查是否创建失败
    if (sServer == INVALID_SOCKET)
    {
        printf("socket failed\n");
        return -1;
    }
    printf("Create socket OK\n");
    //进行绑定操作
    SOCKADDR_IN addrServ;
    addrServ.sin_family = AF_INET; // 协议簇为IPV4的
    addrServ.sin_port = htons(PORT); // 端口  因为本机是小端模式,网络是大端模式,调用htons把本机字节序转为网络字节序
    addrServ.sin_addr.S_un.S_addr = INADDR_ANY; // ip地址,INADDR_ANY表示绑定电脑上所有网卡IP
    //完成绑定操作
    int ret = bind(sServer, (sockaddr *)&addrServ, sizeof(sockaddr));
    //检查绑定是否成功
    if (SOCKET_ERROR == ret)
    {
        printf("socket bind failed\n");
        WSACleanup(); // 释放网络环境
        closesocket(sServer); // 关闭网络连接
        return -1;
    }
    printf("socket bind OK\n");
    // 绑定成功,进行监听
    ret = listen(sServer, 10);
    //检查是否监听成功
    if (SOCKET_ERROR == ret)
    {
        printf("socket listen failed\n");
        WSACleanup();
        closesocket(sServer);
        return -1;
    }
    printf("socket listen OK\n");
    // 监听成功
    sockaddr_in addrClient; // 用于保存客户端的网络节点的信息
    int addrClientLen = sizeof(sockaddr_in);
    while (TRUE)
    {
        //新建一个socket,用于客户端
        SOCKET *sClient = new SOCKET;
        //等待客户端的连接
        *sClient = accept(sServer, (sockaddr*)&addrClient, &addrClientLen);
        if (INVALID_SOCKET == *sClient)
        {
            printf("socket accept failed\n");
            WSACleanup();
            closesocket(sServer);
            delete sClient;
            return -1;
        }
        //创建线程为客户端做数据收发
        CreateThread(0, 0, (LPTHREAD_START_ROUTINE)clientProc, (LPVOID)*sClient, 0, 0);
    }
    closesocket(sServer);
    WSACleanup();
    return 0;
}

客户端:


#include <stdio.h>
#include <winsock2.h>
#include <Windows.h>
#pragma warning(disable:4996)

#pragma comment(lib,"ws2_32.lib")
#define  PORT 6000

int main(int argc, char * argv[])
{
    //初始化网络环境
    WSADATA wsa;
    if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
    {
        printf("WSAStartup failed\n");
        return -1;
    }
    // 初始化完成,创建一个TCP的socket
    SOCKET sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sServer == INVALID_SOCKET)
    {
        printf("socket failed\n");
        return -1;
    }
    //指定连接的服务端信息
    SOCKADDR_IN addrServ;
    addrServ.sin_family = AF_INET;
    addrServ.sin_port = htons(PORT);
    //客户端只需要连接指定的服务器地址,127.0.0.1是本机的回环地址
    addrServ.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

    // 服务器Bind 客户端是进行连接
    int ret = connect(sServer, (SOCKADDR*)&addrServ, sizeof(SOCKADDR));//开始连接
    if (SOCKET_ERROR == ret)
    {
        printf("socket connect failed\n");
        WSACleanup();
        closesocket(sServer);
        return -1;
    }
    //连接成功后,就可以进行通信了
    char szBuf[1024];
    memset(szBuf, 0, sizeof(szBuf));
    sprintf_s(szBuf, sizeof(szBuf), "Hello server");
    //当服务端是recv的时候,客户端就需要send,若两端同时进行收发则会卡在这里,因为recv和send是阻塞的
    ret = send(sServer, szBuf, strlen(szBuf), 0);
    if (SOCKET_ERROR == ret)
    {
        printf("socket send failed\n");
        closesocket(sServer);
        return -1;
    }

    ret = recv(sServer, szBuf, sizeof(szBuf), 0);
    if (SOCKET_ERROR == ret)
    {
        printf("socket recv failed\n");
        closesocket(sServer);
        return -1;
    }
    printf("%s\n", szBuf);

    closesocket(sServer);
    WSACleanup();
    return 0;

}
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
好的,这是一个简单的示例代码,包括服务端客户端的代码: 服务端代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <winsock2.h> #pragma comment(lib, "ws2_32.lib") //链接ws2_32.lib库文件 #define BUF_SIZE 1024 #define PORT 8888 int main() { WSADATA wsaData; SOCKET servSock; SOCKET clntSock; char buffer[BUF_SIZE]; int strLen; SOCKADDR_IN servAddr; SOCKADDR_IN clntAddr; int clntAddrSize; // 初始化Winsock if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { printf("WSAStartup failed!\n"); return 1; } // 创建Socket servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if (servSock == INVALID_SOCKET) { printf("socket failed!\n"); WSACleanup(); return 1; } // 绑定Socket memset(&servAddr, 0, sizeof(servAddr)); servAddr.sin_family = AF_INET; servAddr.sin_addr.s_addr = htonl(INADDR_ANY); servAddr.sin_port = htons(PORT); if (bind(servSock, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR) { printf("bind failed!\n"); closesocket(servSock); WSACleanup(); return 1; } // 监听Socket if (listen(servSock, 5) == SOCKET_ERROR) { printf("listen failed!\n"); closesocket(servSock); WSACleanup(); return 1; } // 接受客户端请求 clntAddrSize = sizeof(clntAddr); clntSock = accept(servSock, (SOCKADDR*)&clntAddr, &clntAddrSize); if (clntSock == INVALID_SOCKET) { printf("accept failed!\n"); closesocket(servSock); WSACleanup(); return 1; } // 与客户端进行通信 while (1) { memset(buffer, 0, BUF_SIZE); strLen = recv(clntSock, buffer, BUF_SIZE, 0); if (strLen == SOCKET_ERROR) { printf("recv failed!\n"); break; } send(clntSock, buffer, strLen, 0); } // 关闭Socket closesocket(clntSock); closesocket(servSock); WSACleanup(); return 0; } ``` 客户端代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <winsock2.h> #pragma comment(lib, "ws2_32.lib") //链接ws2_32.lib库文件 #define BUF_SIZE 1024 #define PORT 8888 int main() { WSADATA wsaData; SOCKET sock; char buffer[BUF_SIZE]; int strLen; SOCKADDR_IN servAddr; // 初始化Winsock if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { printf("WSAStartup failed!\n"); return 1; } // 创建Socket sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock == INVALID_SOCKET) { printf("socket failed!\n"); WSACleanup(); return 1; } // 连接服务器 memset(&servAddr, 0, sizeof(servAddr)); servAddr.sin_family = AF_INET; servAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); servAddr.sin_port = htons(PORT); if (connect(sock, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR) { printf("connect failed!\n"); closesocket(sock); WSACleanup(); return 1; } // 与服务器进行通信 while (1) { memset(buffer, 0, BUF_SIZE); printf("Please input a string: "); gets_s(buffer, BUF_SIZE); if (strcmp(buffer, "exit") == 0) { break; } send(sock, buffer, strlen(buffer), 0); strLen = recv(sock, buffer, BUF_SIZE, 0); if (strLen == SOCKET_ERROR) { printf("recv failed!\n"); break; } printf("Message from server: %s\n", buffer); } // 关闭Socket closesocket(sock); WSACleanup(); return 0; } ``` 注意:以上代码仅供参考,实际使用中还需要进行错误处理和异常情况处理。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值