网络编程实验,windows下的基于udp的客户端登录注册功能

实验名称:基于UDP的编程

实验目的

熟练掌握UDP下的网络编程

实验要求:

熟练掌握UDP下的网络编程,实现相应功能

实验内容:

  • 根据课堂所讲的内容,将TCP的登陆系统修改成UDP的登陆系统。
  • 1、将老师给的TCP的登陆系统解压编译运行,熟悉系统操作。
  • 2、 TCP的登陆系统服务器代码进行修改,修改完成后并运行,用老师给的UDP客户端程序”udp_client.exe”测试它,是否能正常运行。如不行则修改,直到可以为止。
  • 3、 对TCP的登陆系统客户端代码进行修改,修改完成后并运行整个系统。

实验结果:

实验代码

  1. 客户端

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

//

#include "stdafx.h"

bool InitSock()

{

WSADATA wsaData;  

    long iResult = WSAStartup(MAKEWORD(2,2), &wsaData);

    if (iResult != 0)

{       

        return false;

    }

return true;

}

SOCKET CreateTCPSocket() //返回真则成功

{

   SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

if (s == INVALID_SOCKET)

{

         WSACleanup();

      }

      return s;

}

bool Connect(SOCKET s,char *ip,int port)

{

struct sockaddr_in  hints;

hints.sin_family = AF_INET;

hints.sin_port = htons(port);

hints.sin_addr.S_un.S_addr=inet_addr(ip);

int r=connect(s,(struct sockaddr FAR* )&hints,sizeof(hints));

if(r!=0)

{

        r=WSAGetLastError();

        if(r==WSAEWOULDBLOCK)

        {

               printf("%d block\n",r);

       

               r=WSAGetLastError();

               return true;

        }

        return false;

}

return true;

}

int main(int argc, char* argv[])

{

if(!InitSock())

{

        printf("初始化失败!\n");

        return 0;

}

SOCKET s= CreateTCPSocket() ;

//      unsigned long mode=1;

//      ioctlsocket(s,FIONBIO,&mode);

char ip[50]={0};

int port=0;

printf("输入服务器ip地址\n");

scanf("%s",ip);

printf("输入服务器端口号(1024-65535)\n");

scanf("%d",&port);

bool r=Connect(s,ip,port);

if(!r)

{

        printf("连接服务器失败!\n");

        closesocket(s);

        WSACleanup();

        return 0;

}

char user[50]={0};

char pass[50]={0};

printf("请输入用户\n");

scanf("%s",user);

    printf("请输入密码\n");

scanf("%s",pass);

    printf("请选择功能\n");

printf("1  注册\n");

printf("2  登陆\n");

char buf[100]={0};

int n=0;

scanf("%d",&n);

if(n==1)

{

        buf[0]=1;

}

else

{

        buf[0]=2;

}

strcpy(buf+2,user);

strcpy(buf+50,pass);

    int len=send(s,buf,100,0);

if(len!=100)

{

        printf("发送失败!\n");

        closesocket(s);;

        WSACleanup();

        return 0;

       

}

memset((void *)buf,0,100);

aecv:

len=recv(s,buf,100,0);

if(len>0)

{

   if(buf[0]==1)

   {

           if(n==1)

              printf("注册成功!\n");

           else

                  printf("登陆成功!\n");

   }

   else

          printf("登陆成功!\n");

}

    else

{

        printf("接收数据失败!\n");

}

   getchar();

   closesocket(s);;

   WSACleanup();

return 0;

}

服务器端

//服务器端

#include "stdafx.h"

#include <time.h>

#include <iostream>

#include <fstream>

#include <string>    // 包含string头文件

using namespace std; // 使用std命名空间

bool InitSock()

{

    WSADATA wsaData;

    long iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);

    if (iResult != 0)

    {

        return false;

    }

    return true;

}

SOCKET CreateTCPSocket() // 返回真则成功

{

    SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    if (s == INVALID_SOCKET)

    {

        WSACleanup();

    }

    return s;

}

char* GetTime()

{

    time_t t = time(NULL);

    return ctime(&t);

}

bool Bind(SOCKET s, char* Ip, int port)

{

    struct sockaddr_in hints;

    hints.sin_family = AF_INET;

    hints.sin_port = htons(port);

    hints.sin_addr.S_un.S_addr = inet_addr(Ip);

    int r = bind(s, (const sockaddr*)&hints, sizeof(hints));

    if (r == 0)

        return true;

    return false;

}

int GetAllIp(char ip[10][50])

{

    char name[200];

    int r = gethostname(name, 200);

    int i = 0;

    if (r == 0)

    {

        LPHOSTENT p = gethostbyname(name);

        for (i = 0; p->h_addr_list[i] != 0; i++)

        {

            strcpy(ip[i], inet_ntoa(*(struct in_addr*)p->h_addr_list[i]));

        }

    }

    return i;

}

void WriteUser(char* user, char* pass)

{

    std::ofstream file("user.ini", std::ios::app);

    if (file)

    {

        file << user << " " << pass << std::endl;

        file.close();

    }

}

bool ReadUser(char* user, char* pass)

{

    std::ifstream file("user.ini");

    if (file)

    {

        std::string line;

        while (getline(file, line))

        {

            size_t pos = line.find(' ');

            std::string username = line.substr(0, pos);

            std::string password = line.substr(pos + 1);

            if (username == user)

            {

                strcpy(pass, password.c_str());

                file.close();

                return true;

            }

        }

        file.close();

    }

    return false;

}

int main(int argc, char* argv[])

{

    char ip[10][50];

    if (InitSock())

    {

        int i = GetAllIp(ip);

        if (i > 0)

        {

            printf("本机所有的ip地址:\n");

            for (int j = 0; j < i; j++)

                printf("%d %s\n", j, ip[j]);

            printf("请现在服务器ip地址(输入序号):\n");

            scanf("%d", &i);

            printf("请输入端口号(1024-65535):\n");

            int port;

            scanf("%d", &port);

            if (port < 1024 || port >= 65535)

            {

                printf("输入端口号错误!");

                return 0;

            }

            SOCKET s = CreateTCPSocket();

            int r = Bind(s, ip[i], port);

            listen(s, 5);

            struct sockaddr_in addr;

            int len = sizeof(addr);

            while (1)

            {

                char buf[100] = {0};

                SOCKET news = accept(s, (sockaddr*)&addr, &len);

                memset((void*)buf, 0, 100);

                int i = recv(news, buf, 100, 0);

                if (i != 100)

                {

                    printf("接收数据错误!\n");

                }

                char* user = buf + 1;

                char* pass = buf + 50;

                unsigned char cmd = buf[0];

                if (cmd == 1)

                {

                    // 注册

                    char pass1[50] = {0};

                    if (!ReadUser(user, pass1))

                    {

                        WriteUser(user, pass);

                        int n = 1;

                        buf[0] = 1;

                        printf("注册: %s  成功  来自于:%s  时间:%s\n", user, inet_ntoa(*(struct in_addr*)&(addr.sin_addr.S_un.S_addr)), GetTime());

                        send(news, (char*)&n, sizeof(int), 0);

                    }

                    else

                    {

                        int n = 0;

                        printf("注册: %s  失败,用户已存在  来自于:%s  时间:%s\n", user, inet_ntoa(*(struct in_addr*)&(addr.sin_addr.S_un.S_addr)), GetTime());

                        send(news, (char*)&n, sizeof(int), 0);

                    }

                }

                else if (cmd == 2)

                {

                    // 登录

                    char pass1[50] = {0};

                    if (ReadUser(user, pass1))

                    {

                        if (strcmp(pass1, pass) == 0)

                        {

                            int n = 2;

                            printf("登录: %s  成功  来自于:%s  时间:%s\n", user, inet_ntoa(*(struct in_addr*)&(addr.sin_addr.S_un.S_addr)), GetTime());

                            send(news, (char*)&n, sizeof(int), 0);

                        }

                        else

                        {

                            int n = 0;

                            printf("登录: %s  失败,密码错误  来自于:%s  时间:%s\n", user, inet_ntoa(*(struct in_addr*)&(addr.sin_addr.S_un.S_addr)), GetTime());

                            send(news, (char*)&n, sizeof(int), 0);

                        }

                    }

                    else

                    {

                        int n = 0;

                        printf("登录: %s  失败,用户不存在  来自于:%s  时间:%s\n", user, inet_ntoa(*(struct in_addr*)&(addr.sin_addr.S_un.S_addr)), GetTime());

                        send(news, (char*)&n, sizeof(int), 0);

                    }

                }

                closesocket(news);

            }

        }

    }

    return 0;

}

实验心得:

在整个实验过程中,我深刻体会到了TCP和UDP在网络编程中的不同之处。UDP是无连接的、不可靠的传输协议,而TCP是面向连接、可靠的传输协议。在修改登录系统时,我需要注意UDP的特点,保证信息能够正确地传输,并及时处理丢包、重复包等问题。

此外,实验还提醒我重要的网络编程原则,例如错误处理、异常情况处理、数据完整性保证等。在实验过程中,我不断地学习和掌握这些原则,并将其应用到实际的代码中。

总的来说,通过这个实验,我对UDP的网络编程有了更深入的理解,并且掌握了相应的技能。我相信这对我今后的网络编程工作和学习都将有着积极的影响。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值