免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2368 | 回复: 1
打印 上一主题 下一主题

[C++] C++网络编程请教 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-07-29 18:16 |只看该作者 |倒序浏览
有一个服务器和两个客户端,客户端是命令行模式,客户端之间发送的消息要经过服务器处理然后再转发,客户端主线程(main)里用while(1)等待命令输入,然后根据相应的命令在进行操作,另外还建立了一个子线程CreateThread(NULL,0,ReadSock,NULL,0,NULL);用来接收服务器发来的消息, 根据不同的消息类型做相应的响应,现在有一个这样的问题:
在创建的线程里,我要和用户进行交互,(输入Y或者N),问题就出来了,在子线程里用getchar()进行输入时,总是提示无效的命令格式,也就是说,建立的线程里用户输入的字符被当作了命令,请问这种问题怎么解决!
把源程序贴上:
ChatClient.h

#include "windows.h"


class ChatClient
{
public:
        ChatClient(void);
        ~ChatClient(void);
        BOOL InitConnect(UINT port,char *serverIP,UINT port1,char *clientIP);

public:
        SOCKET m_servSocket;        // 服务器socket
        sockaddr_in m_addrServ;        // 保存服务器信息

        // 用户信息
        char m_userName[17];                // 用户名
        LONGLONG m_UserID;                // 用户ID
        char m_Password[11];                // 用户密码

        // 服务器信息
        char m_serverIP[20];                // 服务器IP
        UINT m_servPort;                // 服务器端口

        // 密码策略
        char encodeType[6];                // 保存编码顺序,某次编码不存在时,用'-'表示
        short encodeN[6];                // 若为栅栏编码时,则此数组中对应位置保存栅栏排数,范围1~1024;否则,为0

        // 客户端信息
        sockaddr_in m_addrClient;        // 保存客户端信息
        char m_clientStrIP[20];                // 用于指定客户端通信所用IP
        UINT m_clientPort;                        // 用于指定客户端通信所有端口
};

// 通信消息格式
typedef struct Message
{
        LONGLONG userID[10];                // 用户ID信息数组
        BYTE msgType;                                                        // 消息类型
        BYTE userName[17];                                        // 用户名
        BYTE buf[1950];                                                // 登录、注册时用于保存密码;聊天时,用于存放聊天信息
}MESSAGE;

typedef struct FileTrans // 文件传输
{
        char  serverIP[20];
        UINT serverPort;
        LONGLONG destID;        // 接收端ID
        LONGLONG srcID;                // 发送端ID
        BYTE fileName[512];
        BYTE buf[1950];
}FILETRANS;


console.cpp

#include "ChatClient.h"
#include "CodePro.h"
#include   <iostream>
#include <fstream>
using   namespace   std;

ChatClient cc;
MESSAGE msg;
DWORD WINAPI ReadSock(PVOID pVOID);
BYTE Log_Reg=0;
LONGLONG OLuserID[10];
CodePro codePro;

int main(int argc, char* argv[])
{
        if ( argc < 6 || argc > 9 )
        {
                printf("格式输入出错!\n命令格式:console reg|log USER_ID PASSWORD [USER_NAME] SERV_IP SERV_PORT [CLIENT_IP] [CLIENT_PORT]";
                return 1;
        }
        if ( strcmp(argv[1],"reg" && strcmp(argv[1],"log" )
        {
                printf("格式输入出错!\n命令格式:console reg|log USER_ID PASSWORD [USER_NAME] SERV_IP SERV_PORT [CLIENT_IP] [CLIENT_PORT]";
                return 1;
        }
        cc.m_UserID=(LONGLONG)_atoi64(argv[2]);  //
        strcpy(cc.m_Password,argv[3]); // 保存用户密码

        if (strcmp(argv[1],"reg"==0) // 注册
        {
                if ( argc!=7 && argc!=9 )
                {
                        printf("格式输入出错!\n命令格式:console reg|log USER_ID PASSWORD [USER_NAME] SERV_IP SERV_PORT [CLIENT_IP] [CLIENT_PORT]";
                        return 1;
                }
                strcpy(cc.m_userName,argv[4]);
                strcpy(cc.m_serverIP,argv[5]);
                cc.m_servPort=atoi(argv[6]);
                if( argc == 9 )
                {
                        strcpy(cc.m_clientStrIP,argv[7]);
                        cc.m_clientPort=atoi(argv[8]);
                }
                else
                        strcpy(cc.m_clientStrIP,"不指定";
        }
        else // 登录
        {
                if ( argc!=6 && argc!=8 )
                {
                        printf("4格式输入出错!\n命令格式:console reg|log USER_ID PASSWORD [USER_NAME] SERV_IP SERV_PORT [CLIENT_IP] [CLIENT_PORT]";
                        return 1;
                }
                strcpy(cc.m_serverIP,argv[4]);
                cc.m_servPort=atoi(argv[5]);
                if( argc == 8 )
                {
                        strcpy(cc.m_clientStrIP,argv[6]);
                        cc.m_clientPort=atoi(argv[7]);
                }
                else
                        strcpy(cc.m_clientStrIP,"不指定";
        }

        if( !strcmp(argv[1],"log")
        {
                Log_Reg=1;
        }
       
        cc.InitConnect(cc.m_servPort, cc.m_serverIP, cc.m_clientPort, cc.m_clientStrIP);
        CreateThread(NULL,0,ReadSock,NULL,0,NULL);

        memset(&msg,0,sizeof(MESSAGE));
    msg.msgType=Log_Reg;
        msg.userID[0]=cc.m_UserID;
        strcpy((char *)msg.userName,cc.m_userName);
        strcpy((char *)msg.buf,cc.m_Password);
        send(cc.m_servSocket,(char *)&msg,sizeof(MESSAGE),0);


        while(1)
        {
                char raw[128];
                char buffer[128];
                memset(buffer,0,12;
                memset(raw,0,12;
                gets(raw);
                strcpy(buffer,raw);
               
                // 命令参数分割
                int paramc=0;                                  // 参数个数
                char paramv[10][50];                      // 参数内容
                char *cur;
                char *next;
                if( cur=strtok_s(buffer," \t",&next) )
                {
                        strcpy_s(paramv[paramc],cur);
                        paramc++;
                }
                while( cur=strtok_s(NULL," \t",&next) )
                {
                        strcpy_s(paramv[paramc],cur);
                        paramc++;
                }

                // 发送修改密码消息
                if( !strcmp(paramv[0],"passwd"))
                {
                        char oldPass[11];
                        char newPass[11];
                        memset(&msg,0,sizeof(MESSAGE));
                        msg.msgType=3;
                        msg.userID[0]=cc.m_UserID;
                        strcpy(oldPass,paramv[1]);
                        strcpy(newPass,paramv[2]);
                        strcpy((char *)msg.buf,oldPass);printf("old=%s\n",oldPass);
                        strcpy((char *)msg.userName,newPass);printf("new=%s\n",newPass);
                        send(cc.m_servSocket,(char *)&msg, sizeof(MESSAGE),0);
                }

                // 发送修改加密策略消息
                else if(!strcmp(paramv[0],"cat"))
                {
                        memset(&msg,0,sizeof(MESSAGE));
                        msg.msgType=4;
                        strcpy((char *)msg.buf,paramv[1]);
                        for(int i=0;i<6;i++)
                        {
                                msg.userID=paramv[2]-'0';
                        }
                        send(cc.m_servSocket,(char *)&msg, sizeof(MESSAGE),0);
                }

                // 退出程序
                else if(!strcmp(paramv[0],"quit"))
                {
                        return 0;
                }

                // 发送聊天消息
                else if(!strcmp(paramv[0],"send"))
                {
                        // 查找在线用户列表是否包含目标用户
                        LONGLONG drtUserID=_atoi64(paramv[1]);
                        int i;
                        for( i=0;i<10;i++)
                        {
                                if(OLuserID==drtUserID)
                                        break;
                        }
                        if(i>=10)
                        {
                                printf("该用户当前不在线\n");
                        }
                        else
                        {
                                memset(&msg,0,sizeof(MESSAGE));
                                msg.msgType=2;
                                msg.userID[1]=cc.m_UserID;
                                msg.userID[0]=drtUserID;
                                strcpy((char *)msg.buf,strstr(raw,paramv[2]));

                                //////////////////////////////////////////////////////////////////////////
                                // 根据密码策略进行加密:加密结果放置msg.buf中
                               
                                memcpy( codePro.input, msg.buf, 1950);
                                codePro.len = strlen(codePro.input);
                                for ( int i = 0; i < 6; i++ )
                                {
                                        codePro.CodeInput = cc.encodeType;
                                        codePro.FenceNums = cc.encodeN;
                                }
                                codePro.encode();
                                memcpy( msg.buf, codePro.input, 1950 );

                                send(cc.m_servSocket,(char *)&msg, sizeof(MESSAGE),0);
                        }
                }

                // 查找在线用户
                else if(!strcmp(paramv[0],"look"))
                {
                        cout<<"在线用户:\t";
                        for(int i=0;i<10;i++)
                        {
                                if(OLuserID<0)
                                        break;
                                cout<<OLuserID<<"\t";
                        }
                        cout<<endl;
                }
                else if(!strcmp(paramv[0],"sendfile")) // 传输文件
                {
                        //////////////////////////////////////////////////////////////////////////
                       
                        if(paramc<3)
                        {
                                cout<<"格式不正确"<<endl;
                                cout<<"正确格式:sendfile [recvID] [filepath+filename]"<<endl;
                        }
                        else
                        {
                                //  检查制定目录下文件是否存在
                                ifstream pfile;
                                pfile.open(paramv[2]/*"c:\\1.txt"*/);
                                if(!pfile.is_open())
                                {
                                        cout<<"File does not exits ! please input again."<<endl;
                                }
                                else
                                {
                                        pfile.close();

                                        // 检查接收端在不在线
                                        BOOL flag=FALSE;
                                        for(int i=0;i<10;i++)
                                        {
                                                if(OLuserID<0)
                                                        break;
                                                if(OLuserID==_atoi64(paramv[1]))
                                                {
                                                        flag=TRUE;
                                                        break;
                                                }
                                        }
                                        if(flag==FALSE)
                                        {
                                                cout<<"接收用户当前不在线,请重新选择用户。"<<endl;
                                        }
                                        //  向服务器发送传文件请求
                                        Message msg;
                                        msg.msgType = 5;        // 发送文件请求消息
                                        msg.userID[0] = _atoi64(paramv[1]); // 接收端ID
                                        msg.userID[1] =cc.m_UserID;              // 发送端ID
                                        memcpy(msg.buf,paramv[2],strlen(paramv[2])); // 文件路径+文件名

                                        while(send(cc.m_servSocket,(char *)&msg,sizeof(MESSAGE), 0)<sizeof(MESSAGE))
                                        {
                                                cout<<"文件传输请求发送失败,是否重新发送请求?(Y/N)"<<endl;
                                                if(getchar()=='N')
                                                        break;
                                        }
                                }
                               
                        }

                        //////////////////////////////////////////////////////////////////////////
                }
                else if(!strcmp(paramv[0],"showme")) // 显示本机ID
                {
                        cout<<"本机ID:  "<< cc.m_UserID<<endl;
                }
                else if(!strcmp(paramv[0],"help"))  // 帮助信息
                {
                        cout<<"各命令以及格式:"<<endl;
                        cout<<"1 passwd:修改密码消息 "<<endl;
                        cout<<"2 cat: 修改加密策略"<<endl;
                        cout<<"3 quit: 退出"<<endl;
                        cout<<"4 send: 发送消息"<<endl;
                        cout<<"5 look: 查找在线用户"<<endl;
                        cout<<"6 senfile: 传输文件"<<endl;
                        cout<<"7 showme:查看本机ID"<<endl;
                }
                // 未定义
                else
                {
                        printf("未知的命令类型\n");
                }
                //////////////////////////////////////////////////////////////////////////
        //        recv(cc.m_servSocket,(char *)&msg,sizeof(MESSAGE),0); // 当有文件传输请求时
               
                //////////////////////////////////////////////////////////////////////////

        }
        return 0;
}

// 接收服务器端消息函数
DWORD WINAPI ReadSock(PVOID pVOID)
{
        fd_set fdR;
        struct timeval timeout;
        timeout.tv_sec=1;
        timeout.tv_usec=0;
        MESSAGE msg;

        while(1)
        {
                FD_ZERO(&fdR);
                FD_SET(cc.m_servSocket,&fdR);
               
                switch(select(cc.m_servSocket,&fdR,NULL,NULL,&timeout))
                {
                case -1:
                        printf("select error\n");
                        return FALSE;
                case 0:
                        break;
                default:
                        if(FD_ISSET(cc.m_servSocket,&fdR))
                        {
                                memset(&msg,0,sizeof(MESSAGE));
                                recv(cc.m_servSocket,(char *)&msg,sizeof(MESSAGE),0);
                               
                                // 对接收到你消息分类处理
                                // ID已被注册
                                if ( msg.msgType == 0 )
                                {
                                        for(int i=0;i<10;i++)
                                        {
                                                OLuserID=-1;
                                        }
                                        closesocket(cc.m_servSocket);
                                        cc.m_servSocket=NULL;
                                        printf("[系统提示]  该ID已被注册,请重新注册或登录!\n");
                                        //_exit(1);
                                }

                                // 在线用户ID列表更新
                                if ( msg.msgType == 1 || msg.msgType == 2 )
                                {
                                        // 显示新的在线用户ID列表
                                        for(int i=0;i<10;i++)
                                        {
                                                OLuserID=-1;
                                        }
                                        for ( int i = 0; i < 10; i++ )
                                        {
                                                if ( msg.userID == -1 )
                                                        break;
                                                OLuserID=msg.userID;
                                        }

                                        // 显示系统提示信息
                                        if ( msg.msgType == 1 )
                                                printf("[系统提示]  有用户上线,在线用户ID列表已更新!\n");
                                        else
                                                printf("[系统提示]  有用户离线,在线用户ID列表已更新!\n");
                                }

                                // 各种登录失败消息
                                if ( msg.msgType == 3 || msg.msgType == 4 || msg.msgType == 5 ||
                                        msg.msgType == 7 || msg.msgType == 8 || msg.msgType == 10 )
                                {
                                        for(int i=0;i<10;i++)
                                        {
                                                OLuserID=-1;
                                        }
                                        closesocket(cc.m_servSocket);
                                        cc.m_servSocket=NULL;
                                        if ( msg.msgType == 3 )
                                                printf("[系统提示]  登录失败,该用户ID不存在!\n");
                                        if ( msg.msgType == 4 )
                                                printf("[系统提示]  登录失败,登录密码错误!\n");
                                        if ( msg.msgType == 5 )               
                                                printf("[警告信息]  该用户在别处登录,用户被迫强制下线\n");
                                        if ( msg.msgType == 7 )               
                                                printf("[警告信息]  登录失败:服务器达到用户连接使用上限!\n");
                                        if ( msg.msgType == 8 )       
                                        {       
                                                printf("[系统提示]  注册成功!\n");
                                                printf("[警告信息]  登录失败:服务器达到用户连接使用上限!\n");
                                        }
                                        if ( msg.msgType == 10 )               
                                                printf("密码修改成功,请用新密码重新登录\n");
                                        _exit(1);
                                }

                                // 聊天消息
                                if ( msg.msgType == 6 )
                                {
                                        //////////////////////////////////////////////////////////////////////////
                                        // 根据个人密码策略,对接收到的数据进行解密
               
                                        memcpy(codePro.input, msg.buf, 1950 );
                                        for ( int i = 0; i < 6; i++ )
                                        {
                                                codePro.CodeInput = cc.encodeType[5-i];
                                                codePro.FenceNums = cc.encodeN[5-i];
                                        }
                                        codePro.decode();
                                        memcpy(msg.buf, codePro.input, 1950);

                                        cout<<"recv "<<msg.userID[1]<<" "<<msg.buf<<endl;
                                }

                                // 密码修改失败消息
                                if ( msg.msgType == 9 )
                                {
                                        printf("[系统提示]  旧密码输入错误,密码修改失败!\n");
                                }

                                // 个人密码策略设置更新成功消息
                                if ( msg.msgType == 11 )
                                {
                                        for ( int i = 0; i < 6; i++ )
                                        {
                                                cc.encodeType = (char)msg.buf;
                                                cc.encodeN = (short)msg.userID;
                                        }
                                        printf("[系统提示]  个人密码策略更新成功!\n");
                                }
                                // 文件传输请求
                                if(msg.msgType==12)
                                {
                                        MESSAGE msgSend;
                                        memcpy((char *)&msgSend,(char *)&msg,sizeof(MESSAGE));
                                        cout<<"有ID为"<<msg.userID[1]<<"的用户"
                                                <<"向您传送文件,是否接受?(Y/N)"<<endl;
                                        char c=getchar();
                                        if(c=='N') // 拒绝接受
                                        {
                                                msgSend.msgType = 7;
                                        }
                                        else // 接受请求
                                        {
                                                FILETRANS ft;
                                                ft.destID=msg.userID[0];
                                                ft.srcID=msg.userID[1];
                                                strcpy(ft.serverIP ,cc.m_serverIP);
                                                ft.serverPort = cc.m_servPort;
                                                memcpy(ft.fileName,msg.buf,strlen((char *)msg.buf));
                                                memcpy( ft.buf, msg.buf, 1950 );
                                        }
                                        msgSend.userID[0]=msgSend.userID[1];
                                        msgSend.userID[1]=msgSend.userID[0];
                                        send(cc.m_servSocket,(char *)&msgSend,sizeof(MESSAGE),0); // 将应答发送给服务器
                                }





                        }
                }
        }
}

服务器发来的消息类型为12即 msgType=12时,就有问题了。
请指教。

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
2 [报告]
发表于 2011-07-29 23:01 |只看该作者
要用“代码”方式贴代码。
另外问题描述没看明白
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP