TCP协议(三)之Windows实现

tcp 编程一般的步骤:
server(服务端)
1.new 个 socket
2.bind (IP,port)
3.listen,等待客户端的连接
4.accept 接受客户端的连接
5.接收(recv) 发送数据(send)
6.关闭连接

client(客户端)
1.new 个 socket
2.bind(ip,port)
3.connect (server.ip,server,port)
4.recv() /send()
5.关闭连接

2.程序

服务器程序

#include <stdlib.h>
#include <stdio.h>
#include <WinSock2.h>
#pragma comment(lib,"Ws2_32.lib ")

int main()
{
    WSADATA wsaData;
    struct sockaddr_in servAddr;
    struct sockaddr_in cliAddr;

    if (WSAStartup(MAKEWORD(2, 2), &wsaData))
    {
        printf("Error:RequestWindowsSocketLibrary failed!\n");
        return 0;
    }
    /* 设置IP地址 */
    memset(&servAddr, 0, sizeof(servAddr));
    servAddr.sin_addr.s_addr = htonl(INADDR_ANY); //绑定本机IP
    //servAddr.sin_addr.s_addr = inet_addr("192.168.1.53");

    /* 设置端口 */
    servAddr.sin_family = AF_INET;
    servAddr.sin_port = htons(3000); //端口为3000

    /* 创建套接服务字 */
    SOCKET serverSocket;
    serverSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (serverSocket == INVALID_SOCKET)
    {
        printf("Error:CreatServerSocket failed!\n");
        return 0;
    }

        /* 绑定服务器套接字 */
    if (bind(serverSocket, (sockaddr*)&servAddr, sizeof(sockaddr)) == SOCKET_ERROR) 
    {
        printf("ERROR:Bind failed!\n");
        return 0;
    }

    /* 监听端口 */
    if (listen(serverSocket, 20) == SOCKET_ERROR)
    {
        closesocket(serverSocket);
        WSACleanup();
        printf("ERROR:Listen failed!\n");
        return 0;
    }
    printf("linstening:%dport...\n", ntohs(servAddr.sin_port));

    /* 阻塞方式等待accept */
    int len = sizeof(cliAddr);
    SOCKET clientSocket;
    clientSocket = accept(serverSocket, (sockaddr*)&cliAddr, &len);
    printf("Connected:%s \r\n", inet_ntoa(cliAddr.sin_addr));

    /* 接受消息 */
    char recvBuf[100] = { 0 };
    recv(clientSocket, recvBuf, sizeof(recvBuf), 0);

    /* 发送消息 */
    send(clientSocket, recvBuf, 100, NULL);

    closesocket(clientSocket);
    WSACleanup();
    system("pause");
    return 1;
}

客户端代码

#include "stdlib.h"
#include <stdio.h>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")  //加载 ws2_32.dll

int main()
{
    //初始化DLL
    //主版本号(低字节)为2,副版本号为2,返回 0x0202
    WORD sockVersion = MAKEWORD(2, 2);         
    WSADATA wsaData;
    //WSAStartup() 函数执行成功后,会将与 ws2_32.dll 有关的信息写入 WSAData 结构体变量
    //(只需关注前两个成员即可)
    if (WSAStartup(sockVersion, &wsaData) != 0)   
        return 0;

    //创建套接字,socket() 函数用来创建套接字,确定套接字的各种属性
    //IPv4 地址、面向连接的数据传输方式、TCP 传输协议
    SOCKET sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

    //向服务器发起请求,将创建的套接字与IP地址 101.76.220.219、端口 3000 绑定:
    sockaddr_in sockAddr;
    memset(&sockAddr, 0, sizeof(sockAddr));  
    sockAddr.sin_family = PF_INET;  

    //32位IP地址,s_addr 是一个整数(unsigned long),而IP地址是一个字符串,
    //所以需要 inet_addr() 函数进行转换
    sockAddr.sin_addr.s_addr = inet_addr("101.76.218.229");  

    //16位的端口号,端口号需要用 htons() 函数转换,0~1023 的端口一般由系统分配给特定的服务程序,
    //尽量在 1024~65536 之间分配端口号。
    sockAddr.sin_port = htons(3000);                        
   
    //强制类型转换,服务器端要用 bind() 函数将套接字与特定的IP地址和端口绑定起来,
    //只有这样,流经该IP地址和端口的数据才能交给套接字处理
    while (connect(sock, (SOCKADDR*)& sockAddr, sizeof(SOCKADDR)) == SOCKET_ERROR)
    {
        printf("连接失败\n");
        Sleep(1000);
    }
    printf("成功连接到服务器!\n");

    char sendBuf[100] = {"Hello World"};
    send(sock, sendBuf, 100, NULL);

    char recvBuf[100] = { 0 };
    recv(sock, recvBuf, 100, 0);  

    closesocket(sock);
    WSACleanup();

    for (int i = 0; i < 12; i++)
    {
        printf("%c",recvBuf[i]);
    }

    system("pause");
    return 1;
}
posted @ 2020-06-19 17:44  卖雨伞的小男孩  阅读(575)  评论(0编辑  收藏  举报