vc++socket笔记3-4

 

判断数据是否接收完,有根据双方约定好的长度判断,根据结束符判断,在文件头给定长度判断

 

服务器端(serve):

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include<WinSock2.h>
#include<strsafe.h>
#pragma comment(lib,"Ws2_32.lib")
#define BUF_LEN 300
using namespace std;
int main()
{
    WORD wVersionRequested;
    WSADATA wsaData;
    int err, iRes,i;// 错误码
    wVersionRequested = MAKEWORD(2, 2);// 版本号
    err = WSAStartup(wVersionRequested, &wsaData);
    if (err != 0)return 0;
    if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)// 如果版本号低8位不为2或高8位不为2则版本号错误,不知道有什么意义
    {
        WSACleanup();
        return 0;
    }
    SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);
    SOCKADDR_IN addrSrv;
    addrSrv.sin_addr.S_un.S_addr = htonl(ADDR_ANY);
    // addrSrv.sin_addr.S_un.S_addr = inet_addr("192.168.1.2");
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(11451);
    bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
    listen(sockSrv, 5);
    SOCKADDR_IN addrClient;
    int len = sizeof(SOCKADDR);
    int cn = 0;
    while (1)
    {
        printf("----------等待客户端------------\n");
        SOCKET sockConn = accept(sockSrv, (SOCKADDR*)&addrClient, &len);
        char sendBuf[111];
        for (cn = 0;cn < 50;i++)
        {
            memset(sendBuf, 'a', 111);
            if (cn == 49)
                sendBuf[110] = 'b';
            send(sockConn, sendBuf, 111, 0);
        }
        char recBuf[BUF_LEN];
        do
        {
            iRes = recv(sockConn, recBuf, BUF_LEN, 0);
            if (iRes > 0)
            {
                printf("\nRecv %d bytes:", iRes);
                for (int i = 0;i < iRes;i++)printf("%c", recBuf[i]);
                printf("\n");
            }
            else if (iRes == 0)printf("\n客户端关闭连接\n");
            else
            {
                printf("recv failed with error:%d\n", WSAGetLastError());
                closesocket(sockConn);
                WSACleanup();
                return 1;
            }
        } while (iRes > 0);
        
        closesocket(sockConn);
        puts("是否继续监听(y/n)");
        char ch[2];
        scanf_s("%s", ch, 2);
        if (ch[0] != 'y')break;
    }
    closesocket(sockSrv);
    WSACleanup();
    return 0;
}

客户端(client):

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include<WinSock2.h>
#include<strsafe.h>
#pragma comment(lib,"Ws2_32.lib")
#define BUF_LEN 300
using namespace std;
int main()
{
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;// 错误码
    u_long argp;
    char szMsg[] = "你好服务器,我已经收到你的信息";
    wVersionRequested = MAKEWORD(2, 2);// 版本号
    err = WSAStartup(wVersionRequested, &wsaData);
    if (err != 0)return 0;
    if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)// 如果版本号低8位不为2或高8位不为2则版本号错误,不知道有什么意义
    {
        WSACleanup();
        return 0;
    }
    SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);
    SOCKADDR_IN addrSrv;
    addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    // addrSrv.sin_addr.S_un.S_addr = inet_addr("192.168.1.2");
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(11451);
    err = connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
    if (SOCKET_ERROR == err)
    {
        printf("连接服务器失败\n");
        return 0;
    }
    char recvBuf[BUF_LEN];
    int i, cn = 1, iRes;
    int leftlen = 50 * 111;
    while (leftlen > 0)
    {
        iRes = recv(sockClient, recvBuf, BUF_LEN, 0);
        if (iRes > 0)
        {
            printf("\nNO.%d Recv %d bytes:", cn++, iRes);
            for (i = 0;i < iRes;i++)
                printf("%c", recvBuf[i]);
            printf("\n");
        }
        else if (iRes == 0)puts("\n服务器端关闭发送连接\n");
        else
        {
            printf("recv failed:%d\n", WSAGetLastError());
            printf("recv failed with error:%d\n", WSAGetLastError());
            closesocket(sockClient);
            WSACleanup();
            return 1;
        }
        leftlen = leftlen - iRes;
    }

    char sendBuf[100];
    sprintf_s(sendBuf, "我是客户端,我已经完成数据接受了\0");
    send(sockClient, sendBuf, sizeof(sendBuf) + 1, 0);
    memset(sendBuf, 0, sizeof(sendBuf));
    puts("向服务器端发送数据完成");
    closesocket(sockClient);
    system("pause");// 卡屏
    WSACleanup();
    return 0;
}

 

服务器端(serve):

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include<WinSock2.h>
#include<strsafe.h>
#pragma comment(lib,"Ws2_32.lib")
#define BUF_LEN 300
using namespace std;
struct MyData
{
    int nLen;
    char data[0];
};
int main()
{
    WORD wVersionRequested;
    WSADATA wsaData;
    int err, iRes,i;// 错误码
    wVersionRequested = MAKEWORD(2, 2);// 版本号
    err = WSAStartup(wVersionRequested, &wsaData);
    if (err != 0)return 0;
    if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)// 如果版本号低8位不为2或高8位不为2则版本号错误,不知道有什么意义
    {
        WSACleanup();
        return 0;
    }
    SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);
    SOCKADDR_IN addrSrv;
    addrSrv.sin_addr.S_un.S_addr = htonl(ADDR_ANY);
    // addrSrv.sin_addr.S_un.S_addr = inet_addr("192.168.1.2");
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(11451);
    bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
    listen(sockSrv, 5);
    SOCKADDR_IN addrClient;
    int len = sizeof(SOCKADDR);
    int cn = 0;
    struct MyData* mydata;
    while (1)
    {
        printf("----------等待客户端------------\n");
        SOCKET sockConn = accept(sockSrv, (SOCKADDR*)&addrClient, &len);
        cn = 5550;
        {
            mydata = (MyData*)malloc(sizeof(MyData) + cn);
            mydata->nLen = htonl(cn);
            memset(mydata->data, 'a', cn);
            mydata->data[cn - 1] = 'b';
            send(sockConn, (char*)mydata, sizeof(MyData) + cn, 0);
            free(mydata);
        }
        char recBuf[BUF_LEN];
        do
        {
            iRes = recv(sockConn, recBuf, BUF_LEN, 0);
            if (iRes > 0)
            {
                printf("\nRecv %d bytes:", iRes);
                for (int i = 0;i < iRes;i++)printf("%c", recBuf[i]);
                printf("\n");
            }
            else if (iRes == 0)printf("\n客户端关闭连接\n");
            else
            {
                printf("recv failed with error:%d\n", WSAGetLastError());
                closesocket(sockConn);
                WSACleanup();
                return 1;
            }
        } while (iRes > 0);
        
        closesocket(sockConn);
        puts("是否继续监听(y/n)");
        char ch[2];
        scanf_s("%s", ch, 2);
        if (ch[0] != 'y')break;
    }
    closesocket(sockSrv);
    WSACleanup();
    return 0;
}

客户端(client):

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include<WinSock2.h>
#include<strsafe.h>
#pragma comment(lib,"Ws2_32.lib")
#define BUF_LEN 300
using namespace std;
int main()
{
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;// 错误码
    u_long argp;
    char szMsg[] = "你好服务器,我已经收到你的信息";
    wVersionRequested = MAKEWORD(2, 2);// 版本号
    err = WSAStartup(wVersionRequested, &wsaData);
    if (err != 0)return 0;
    if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)// 如果版本号低8位不为2或高8位不为2则版本号错误,不知道有什么意义
    {
        WSACleanup();
        return 0;
    }
    SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);
    SOCKADDR_IN addrSrv;
    addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    // addrSrv.sin_addr.S_un.S_addr = inet_addr("192.168.1.2");
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(11451);
    err = connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
    if (SOCKET_ERROR == err)
    {
        printf("连接服务器失败\n");
        return 0;
    }
    char recvBuf[BUF_LEN];
    int i, cn = 1, iRes;
    int leftlen;// = 50 * 111;
    unsigned char* pdata;
    iRes = recv(sockClient, (char*)&leftlen, sizeof(int),0);
    leftlen = ntohl(leftlen);
    while (leftlen > 0)
    {
        iRes = recv(sockClient, recvBuf, BUF_LEN, 0);
        if (iRes > 0)
        {
            printf("\nNO.%d Recv %d bytes:", cn++, iRes);
            for (i = 0;i < iRes;i++)
                printf("%c", recvBuf[i]);
            printf("\n");
        }
        else if (iRes == 0)puts("\n服务器端关闭发送连接\n");
        else
        {
            printf("recv failed:%d\n", WSAGetLastError());
            printf("recv failed with error:%d\n", WSAGetLastError());
            closesocket(sockClient);
            WSACleanup();
            return 1;
        }
        leftlen = leftlen - iRes;
    }

    char sendBuf[100];
    sprintf_s(sendBuf, "我是客户端,我已经完成数据接受了\0");
    send(sockClient, sendBuf, sizeof(sendBuf) + 1, 0);
    memset(sendBuf, 0, sizeof(sendBuf));
    puts("向服务器端发送数据完成");
    closesocket(sockClient);
    system("pause");// 卡屏
    WSACleanup();
    return 0;
}

注意传送整型数据时要将数据转为大端存储,也就是网络字节序,这是个良好的习惯。而且本机或局域网下这么做貌似能得到正确的结果,但是路由器网络环境上好像有问题。

效果如上图,懒得截。

 

posted @ 2022-03-22 15:41  才出昆仑便不清  阅读(51)  评论(0)    收藏  举报