简单的TCP程序客户端流程:创建套接字(套接字用IP地址:端口号)表示)socket()->请求连接connect()->交换数据 send()/recv()->关闭连接 closesocket()

简单的TCP程序服务端流程:创建套接字socket()->绑定相应的端口bind()->监听端口listen()->接受连接accept()->交换数据recv()/send()->关闭连接 closesocket()

第一个网络程序

代码实现:

TcpServer.cpp

TcpClient.cpp

在其基础上,更进一步,实现一个基于简单TCP的用户注册程序,实现下列功能

客户端发送用户注册信息(用户名、密码和其他资料)到服务器端; 服务器端首先检查用户注册数据是否符合格式。如不符合则返回“非法访问”提示; 如符合检查用户文件中是否存在相同用户名,如不存在,则将用户注册信息存放到用户文件中,返回“用户注册成功”提示 如用户文件中存在相同用户名,则返回“用户名已被注册”。

主要的实现函数:

//将用户键入的数据放到User结构体中
User Input_Info(const char* message);

//判断用户键入的全部数据的是否符合格式
int Is_Valid_Format(const User user);

//分别判断用户名、密码、手机号码是否符合格式
int Is_Valid_Format_Of_Name(const char* name);
int Is_Valid_Format_Of_Password(const char* pass);
int Is_Valid_Format_Of_PhoneNumber(const char* phone);

//主要的验证函数
void Main_Process_Info(const User user,const SOCKET sNewConnection);

//判断该用户名是否已经被注册(也就是说该用户名有没有存在于用户文件中)
int Is_Name_Exist(const char* name);

//将新的用户信息写入到文件中
int Write_Info_To_Txt(const User user);

/****每个函数的具体代码***/

User Input_Info(const char* message)
{
User user;
char userName[20] = {0},
password[20] = { 0 }, phoneNumber[20] = {0};
// user = { '\0', '\0', '\0' };
//user.userName = {0};

sscanf(message, "%s\t%s\t%s", user.userName,
user.password, user.phoneNumber);

/*printf("%s\t%s\t%s", user.userName,
user.password, user.phoneNumber);*/
/* sscanf(message, "%s\t%s\t%s", userName,
password, phoneNumber);
printf("%s\t%s\t%s", userName,
password, phoneNumber);*/
return user;
}

int Is_Valid_Format(const User user)
{
int flag = 0;
if (Is_Valid_Format_Of_Name(user.userName)&&
Is_Valid_Format_Of_Password(user.password)&&
Is_Valid_Format_Of_PhoneNumber(user.phoneNumber))
{
return 1;
}
else
{
return 0;
}
}

int Is_Valid_Format_Of_Name(const char* name)
{
if (strlen(name) >= 6 && strlen(name) <= 12)
return 1;
else
return 0;

}
int Is_Valid_Format_Of_Password(const char* pass)
{
if (strlen(pass) >= 8 && strlen(pass) <= 24)
return 1;
else
return 0;
}
int Is_Valid_Format_Of_PhoneNumber(const char* phone)
{
if (strlen(phone)==11)//先判断长度是不是11位,接着判断是不是全部是数字
{
for (int i = 0; i < 11; i++)
{
if (phone[i] >= '0'&&phone[i] <= '9')
{
continue;
}
else
{
break;
return 0;
}

}
return 1;
}
else
{
return 0;
}
}

int Is_Name_Exist(const char* name)
{
//打开用户文件,将该用户名和文件中的用户名一个个比较,
//看看是否已经有相同的用户名存在了
char* file_name = "user.txt";
if (access(file_name, 0))
{
//printf("D://user.txt doesn't exist!");
//printf("then create!");
char* file_name = "user.txt";
FILE *fp = fopen(file_name, "at+");
}
//将文件中的记录一条条的都出来
//假定每一条记录承载每一个用户的全部信息
//第一条字符串是用户的name
char buf[MAX_SIZE];/*缓冲区*/
FILE* fp=NULL;
if ((fp=fopen("user.txt","r"))==NULL)//该文件和.cpp文件放在同一个父目录下
{
printf("Failed to read!");
exit(1);
}
while (fgets(buf,MAX_SIZE,fp)!=NULL)
{
//char* temp_name;//会出现停止工作的情况
char temp_name[256] = { '\0' };
char temp_pass[512] = { '\0' };
char temp_phone[256] = { '\0' };
sscanf(buf, "%s\t%s\t%s", temp_name,temp_pass,temp_phone);
if (strcmp(temp_name,name)==0)//该用户名已被注册,该用户名在文件中存在
{
return 1;
}
else
{
continue;
}
}
return 0;//该用户名未被注册,该用户名不在用户文件中存在

}

void Main_Process_Info(const User user,const SOCKET sNewConnection)
{
char msg[256] = {'\0'};
if (Is_Valid_Format(user))//如果用户注册数据符合格式
{
if (!Is_Name_Exist(user.userName))
{
//将该用户的注册信息写入用户文件中
if (Write_Info_To_Txt(user))
{
strcpy(msg, "用户注册成功!\n");
send(sNewConnection,msg,sizeof(msg),0);
printf("用户注册成功!\n");
}
else
{
strcpy(msg, "用户注册失败!(未能将新用户信息成功写入用户文件中)\n");
send(sNewConnection, msg, sizeof(msg), 0);
printf("用户注册失败!(未能将新用户信息成功写入用户文件中)\n");
}

}
else
{
strcpy(msg, "该用户名已经被注册了!\n");
send(sNewConnection, msg, sizeof(msg), 0);
printf("该用户名已经被注册了!\n");
}
}
else
{
strcpy(msg, "非法访问!\n");
send(sNewConnection, msg, sizeof(msg), 0);
printf("非法访问!\n");
}
}

int Write_Info_To_Txt(const User user)
{
FILE* fp;
char* filename = "user.txt";
if ((fp=fopen(filename,"a"))==NULL)
{
printf("\n 不能打开该用户文件!\n");
return 0;
}
fprintf(fp,"%s\t%s\t%s\n",user.userName,user.password,user.phoneNumber);
printf("%s\t%s\t%s\n", user.userName, user.password, user.phoneNumber);
fclose(fp);
return 1;
}

运行结果截屏如下:

客户端:

服务端:

用户信息文件:

network programming-简单的TCP客户服务器编程的更多相关文章

  1. 【unix网络编程第三版】阅读笔记(四):TCP客户/服务器实例

    本篇博客主要记录一个完整的TCP客户/服务器实例的编写,以及从这个实例中引发的对僵死进程的处理等问题. 1. TCP客户/服务器功能需求 本实例完成以下功能: (1) 客户从标准输入读入一行文本,并写 ...

  2. UNIX网络编程 第5章 TCP客户/服务器程序示例

    UNIX网络编程 第5章 TCP客户/服务器程序示例

  3. 系统编程-网络-tcp客户端服务器编程模型(续)、连接断开、获取连接状态场景

    相关博文: 系统编程-网络-tcp客户端服务器编程模型.socket.htons.inet_ntop等各API详解.使用telnet测试基本服务器功能 接着该上篇博文,咱们继续,首先,为了内容的完整性 ...

  4. 【Unix 网络编程】TCP 客户/服务器简单 Socket 程序

    建立一个 TCP 连接时会发生下述情形: 1. 服务器必须准备好接受外来的连接.这通常通过调用 socket.bind 和 listen 这三个函数来完成,我们称之为被动打开. 2. 客户通过调用 c ...

  5. UNP学习笔记2——从一个简单的ECHO程序分析TCP客户/服务器之间的通信

    1 概述 编写一个简单的ECHO(回复)程序来分析TCP客户和服务器之间的通信流程,要求如下: 客户从标准输入读入一行文本,并发送给服务器 服务器从网络输入读取这个文本,并回复给客户 客户从网络输入读 ...

  6. TCP客户/服务器简单Socket程序

    建立一个 TCP 连接时会发生下述情形: 1. 服务器必须准备好接受外来的连接.这通常通过调用 socket.bind 和 listen 这三个函数来完成,我们称之为被动打开. 2. 客户通过调用 c ...

  7. 第四章 基本TCP套接字编程 第五章 TCP客户/服务器程序实例

    TCP客户与服务器进程之间发生的重大事件时间表 TCP服务器 socket() --- bind() --- listen() --- accept() --- read() --- write -- ...

  8. --系统编程-网络-tcp客户端服务器编程模型、socket、htons、inet_ntop等各API详解、使用telnet测试基本服务器功能

    PART1 基础知识 1. 字节序 网络字节序是大端字节序(低地址存放更高位的字节), 所以,对于字节序为小端的机器需要收发网络数据的场景,要对这些数据进行字节序转换. 字节序转换函数,常用的有四个: ...

  9. TCP客户/服务器程序实例——回射服务器

    目录 客户/服务器程序源码 POSIX信号处理 POSIX信号语义 处理SIGCHLD信号 处理僵死进程 处理被中断的系统调用 wait和waitpid函数 wait和waitpid函数的区别 网络编 ...

随机推荐

  1. 关键字final整理

    关键字final整理 由于语境(应用环境)不同,final 关键字的含义可能会稍微产生一些差异.但它最一般的意思就是声明"这个东西不能改变".之所以要禁止改变,可能是考虑到两方面的 ...

  2. OkHttp自定义重试次数

    本文主要应用了OkHttp的Interceptor来实现自定义重试次数 虽然OkHttp自带retryOnConnectionFailure(true)方法可以实现重试,但是不支持自定义重试次数,所以 ...

  3. IO (五)

    1 序列化和反序列化 1.1 ObjectOutputStream 序列化 1.1.1 概述 ObjectOutputStream将Java对象的基本数据写入OutputStream,可以使用Obje ...

  4. shell第一篇

    前两天不停的再看内核相关的内容,了解内核的形成.内核的执行流程.内核的作用,结果是舍近求远. 其实我只是想了解一下shell的工作,shell与内核有关,但并不需要我么真正去做什么,至少对于我这样额初 ...

  5. 【转】GPS连续运行单参考站解决方案

    GPS连续运行单参考站解决方案   一.  前言 随着国家信息化程度的提高及计算机网络和通信技术的飞速发展,电子政务.电子商务.数字城市.数字省区和数字地球的工程化和现实化,需要采集多种实时地理 空间 ...

  6. TCP/IP详解 卷1 第二十一章 TCP的超时与重传

    21.1 引言 可靠性的保证之一就是超时重传 前面两个超时重传的例子 1)  ICMP端口不能到达时,TFTP客户使用UDP实现了一个简单的超时和重传机制,假定5s是一个适当是时间间隔,并每隔5s进行 ...

  7. dump、libeay32.dll、gsoap、webserver多线程调用gsoap产生崩溃

    问题:调用webserver接口出现dump文件,dump文件指向libeay32.dll有问题,产生崩溃的原因是gsoap多线程问题,多线程调用时需要程序启动的地方调用如下函数进行多线程初始化: i ...

  8. Jmeter之性能测试类型

    pipe-clean test 在测试环境预先跑 确定脚本准确性 单用户跑 获取baseline   容量测试 经典的性能测试类型 获取系统稳定运行时最大的吞吐量/并发数/响应时间时 尽量模拟真实情况 ...

  9. Django中模板的用法简介

    1. 模板系统的介绍 Django作为一个Web框架,其模板所需的HTML输出静态部分以及动态内容插入 模板由HTML代码和逻辑控制代码构成 Django框架的模板语言的语法格式: {{var_nam ...

  10. JDBC学习笔记(三)

    获取数据库的元信息metadata,里面有数据库特性的描述信息,如是否支持事务,是否支持批处理等. Connection conn = DriverManager.getConnection(url, ...