•实现一个基于简单TCP的用户注册程序,实现下列功能
–客户端发送用户注册信息(用户名、密码和其他资料)到服务器端;
–服务器端首先检查用户注册数据是否符合格式。如不符合则返回“非法访问”提示;
–如符合检查用户文件中是否存在相同用户名,如不存在,则将用户注册信息存放到用户文件中,返回“用户注册成功”提示
如用户文件中存在相同用户名,则返回“用户名已被注册
客户端程序
#include <stdio.h> #include <winsock.h> #include<string.h> #pragma comment(lib, "ws2_32.lib")//这句话的前面意思是静态加入一个lib文件也就是库文件ws2_32.lib文件,提供了对以下网络相关API的支持,若使用其中的API,则应该将ws2_32.lib加入工程(否则需要动态载入ws2_32.dll)。 int main(int argc, char *argv[]) { //int First,Second; //step 1: 初始化Windows Socket 2.2库 WSADATA wsaData;//功能是:存放windows socket初始化信息 WSAStartup(MAKEWORD(2,2), &wsaData); //step 2: 创建客户端SOCKET套接字 SOCKET sClient = socket(AF_INET, SOCK_STREAM, 0); //step 3: 设置服务器地址 sockaddr_in serverAddr; memset(&serverAddr, 0, sizeof(sockaddr_in));//去掉没有影响,暂时不知用途 /*void *memset(void *s, int ch, size_t n); 函数解释:将s中当前位置后面的n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s 。 memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法*/ serverAddr.sin_family = AF_INET; //serverAddr.sin_addr.s_addr = inet_addr(argv[1]); //serverAddr.sin_port = htons((u_short)atoi(argv[2])); serverAddr.sin_addr.s_addr =inet_addr("127.0.0.1"); //serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); serverAddr.sin_port = htons(5150); //step 4: 连接服务器 connect(sClient, (SOCKADDR *)&serverAddr, sizeof(serverAddr));//sockaddr和sockaddr_in的区别:二者的占用的内存大小是一致的,因此可以互相转化,从这个意义上说,他们并无区别 //step 5:与服务器进行通讯 printf("%s\n","正在启动用户注册程序:"); while(1) { char data[1024]={0},buf[100]={0}; //录入基本信息 printf("%s","用户名(学号或8位字符串):"); scanf("%s",data); printf("%s","密码(8-30字符):"); scanf("%s",buf); strcat(data,"+"); strcat(data,buf); printf("%s","姓名:"); scanf("%s",buf); strcat(data,"+"); strcat(data,buf); printf("%s","性别:"); scanf("%s",buf); strcat(data,"+"); strcat(data,buf); printf("%s","年龄:"); scanf("%s",buf); strcat(data,"+"); strcat(data,buf); //FILE *fp=fopen("use.txt","a"); //fprintf(fp,"%s\n",data); //fclose(fp); send(sClient, data, strlen(data)+1, 0);//第三个参数是缓冲区中数据的长度,返回所发送的数据的总长度或SOCKET_ERROR错误 recv(sClient, data, 1024, 0);//第三个参数是缓冲区的长度;成功执行时,返回接收到的字节数。另一端已关闭则返回0。失败返回-1 printf("%s\n",data); recv(sClient, data, 1024, 0); printf("%s\n",data); } //step 6:关闭套接字 closesocket(sClient); //step 7:释放Winsock库 WSACleanup(); getchar(); getchar(); return 0; }
#pragma comment(lib, "ws2_32.lib")//预编译 #include <stdio.h> #include <winsock2.h> int main(int argc, char *argv[]) { //step1:初始化Windows Socket 2.2库 WSADATA wsaData; WSAStartup(MAKEWORD(2,2), &wsaData); //step2:创建一个新的Socket来响应客户端的连接请求 SOCKET sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //step3:填写服务器地址信息 int port = 5150;// 端口为5150 SOCKADDR_IN serverAddr; serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(port); //serverAddr.sin_addr.s_addr =inet_addr("10.66.103.187"); serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); //IP地址为INADDR_ANY,使用htonl将IP地址转换为网络格式 //step4:绑定监听端口 bind(sListen, (SOCKADDR *)&serverAddr, sizeof(serverAddr)); //step5:开始监听,指定三次握手等待队列长度为5 listen(sListen, 5); printf("开始监听......\n"); while(true) { //step6:接受新的连接 SOCKET sNewConnection; SOCKADDR_IN clientAddr; memset(&clientAddr, 0, sizeof(clientAddr)); int clientAddrLen = sizeof(clientAddr); sNewConnection = accept(sListen, (SOCKADDR *)&clientAddr, &clientAddrLen); //step7:新的连接建立后,就可以互相通信了, //在这个简单的例子中, //我们发送"Welcome to Network Programing!",然后关闭连接 //进行数据交换 while(1) { char message[1024]={0},buf[100]={0},messagebuf[1024]={0};//message收发信息,buf错误信息,操作messagebuf收发信息 int i=0,j=0;//i标记是否成功注册,j标记用户名是否已存在 int recvSize=recv(sNewConnection,message, sizeof(message), 0);//接收数据 if(recvSize <= 0)//判断是否接收成功 break; strcpy(messagebuf,message);//对messagebuf赋值 //对接收的数据进行验证 char *use,*pass,*name,*sex,*age; use=strtok(messagebuf,"+"); pass=strtok(NULL,"+"); name=strtok(NULL,"+"); sex=strtok(NULL,"+"); age=strtok(NULL,"+"); printf("注册信息为:%s %s %s %s %s\n",use,pass,name,sex,age); strcpy(buf,"非法访问!"); while(1) { if(strlen(use)!=8) { i=1; send(sNewConnection, buf, strlen(buf)+1, 0); break; } if(!(strlen(pass)>7&&strlen(pass)<31)) { i=1; send(sNewConnection, buf, strlen(buf)+1, 0); break; } if(strcmp(sex,"男")&&strcmp(sex,"女")) { i=1; send(sNewConnection, buf, strlen(buf)+1, 0); break; } strcpy(buf,"数据合法!"); send(sNewConnection, buf, strlen(buf)+1, 0); break; } //检验是否注册 FILE *fp = fopen("use.txt", "r");; while(!feof(fp)&&i==0) { char *used; char szTest[1000] = {0}; fgets(szTest, sizeof(szTest) - 1, fp); // 包含了\n used=strtok(szTest,"+"); if(!strcmp(use,used)) { j=1; i=1; break; } } fclose(fp); //如果未注册则保存 if(i==0) { fp = fopen("use.txt", "a"); fprintf(fp,"\n%s",message); fclose(fp); strcpy(buf,"注册成功!"); send(sNewConnection, buf, strlen(buf)+1, 0); } else//如果数据不合法或者用户已存在则返回提示信息 { if(j==1) { strcpy(buf,"用户名已存在!"); send(sNewConnection, buf, strlen(buf)+1, 0); } else { strcpy(buf,"注册失败!"); send(sNewConnection, buf, strlen(buf)+1, 0); } } } //关闭与客户通讯的套接字 closesocket(sNewConnection); printf("%s\n","另一端关闭"); } //step8:关闭套接字 closesocket(sListen); //step9:释放Windows Socket DLL的相关资源 WSACleanup(); return 0; }
最后结果
use.txt内容如下(注意,use.txt中预先至少有一条记录)
14071201+asdfdsafs+张三+男+14
14071202+fasdfdsaf+李四+男+14