首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ Builder >

求socket通讯有关问题

2012-04-07 
求socket通讯问题客户端通过socket与主机进行通讯,如果多个用户同时向主机发送数据,则返回结果是错误的,一

求socket通讯问题
客户端通过socket与主机进行通讯,如果多个用户同时向主机发送数据,则返回结果是错误的,一个用户则不会出现错误,网上发了一些贴子,说问题不在客户端,应该是服务端的问题,服务端是UNIX C,客户端是vb.net,客户端代码发过多次,分别是:
http://topic.csdn.net/u/20110812/14/7a58d6e1-d4f0-4fa7-8b61-5966cc752c7b.html
http://topic.csdn.net/u/20110811/17/8d35d1d8-1eba-4a16-baa5-9d8c5edb0f91.html
http://topic.csdn.net/u/20110811/17/254e841c-9fbb-424b-8719-13e3c9439657.html
http://topic.csdn.net/u/20110722/10/93ea23fe-ab02-4ea6-9ca9-a33f5a1d7133.html
http://topic.csdn.net/u/20110708/10/6c17351c-92da-4ee8-88b5-7a1c2435395e.html

C语言不是太懂,发出来大家给看下,到底是哪里出了问题,这个问题一直没有解决,非常郁闷。

C/C++ code
#include "svceft.h"struct    timeval     TimeOut;fd_set     rset,rs;int        MaxFd = -1;int    NowSocketNum,SckPort[MAX_SOCKET_CONN+1];int    msgQid_in,msgQid_out,CPDout[2];char    CpdTraceFile[50];/*系统参数变量定义*/char *g_Mode, *g_HOSTIP, *g_HOSTPORT, *g_MYQ_in,*g_MYQ_out,*g_RHCSPATH,*g_RHFTPIP,*g_MAXLINE,*g_PACKTYPR;char *g_MY_IN_TYPE,*g_MY_OUT_TYPE;key_t MQ_KEY_in,MQ_KEY_out;void DB_Initialize();void ReadQueChild();void NAC_socket();int  HexToInt(char *str,int len);//消息结构体WhMsgStruBuf_web    MsgStruBuf;FILE    *fp;char    inst[5+1];int main(int argc, char **argv){    int    TOpen,ChildPid;            //屏蔽信号SIGPIPE,当发送信息给disconnected scoket时会引发PIPE信号    //导致进程退出(程序退去),故屏蔽     signal(SIGPIPE,SIG_IGN);     //当前socket数目     NowSocketNum = 1;    //清空文件描述符集合    FD_ZERO(&rset);          if (argc != 2){            printf("Usage: %s <string>\n", argv[0]);                exit(2);       }                memset(inst,0,sizeof(inst));        memcpy(inst,argv[1],5);          /*pid = fork();    if(pid < 0) {        printf("fork 1111 ,error=%d\n",errno);        exit(0);    }    else if(pid > 0) {        exit(0);    }                setsid();    setpgrp();*/    //初始化相关变量,从配置文件中读取    DB_Initialize();          SckPort[0] = atoi(g_HOSTPORT);     SckPort[1] = atoi(g_HOSTPORT);          memset(&ServerInfo,0,sizeof(ServerInfo));          //消息队列id     MQ_KEY_in = atoi(g_MYQ_in);     MQ_KEY_out = atoi(g_MYQ_out);    InitProcess_Para();                            ChildPid=fork();            if(ChildPid==0)                ReadQueChild();            else if(ChildPid>0)                NAC_socket();            else if(ChildPid==-1)            {                printf("\nChild Create error!\n");                exit(0);            }}//服务端void NAC_socket(){    FILE    *fp,*fp1;    char    buf[MAX_BUF_SIZE_WEB+1],TmpCharBuf[100],TmpBuf[15];    long     Len,MsgLen;    int    ii,n;    unsigned long  nLen;    int    Error;    int    WkErr;    int     Flag,TmpSock;    int     lockfd;    WhMsgStruBuf_web    MsgStruBuf;        WhMsgpipeBuf            MsgpipeBuf;    //当前socket数目     NowSocketNum = 1;                TimeOut.tv_sec=10;//秒    TimeOut.tv_usec=0;//        WkErr=0;        for(ii=0;ii<NowSocketNum;ii++)    {        TmpSock=AddServerSocketSet(ServerInfo[ii].Port,ServerInfo[ii].SerAddrIp,&rset,&MaxFd);        if(TmpSock >= 0)        {            ServerInfo[ii].LsnSock=TmpSock;        }    }    while(1){        rs=rset;        //参数:第二个参数指向一组等待可读性检查的套接口        //第三个参数指向一组等待可写性检查的套接口           n=select(MaxFd+1,&rs,NULL,NULL,&TimeOut);           if(n<0&&errno!=EINTR){               sprintf(TmpCharBuf,"select errno or timeout.errno=[%d]",errno);               MyTracePrint(TmpCharBuf);            continue;           }                getdatetimes(TmpCharBuf,2); /* YYYYMMDDhhssmm */        TmpCharBuf[8]=0;        sprintf(CpdTraceFile,"../log/cpd_web%s.log",TmpCharBuf);        //管道        if(FD_ISSET(CPDout[0],&rs)) {            memset(&MsgStruBuf,0,sizeof(MsgStruBuf));//            /*读取通讯端口*///            if(readn(CPDout[0],&MsgStruBuf.LineNo,sizeof(int))<=0){//                   sprintf(TmpCharBuf,"read pipeSerToCpd[0] err(1) ,errno=[%d]",errno);//                MyTracePrint(TmpCharBuf);//                perror("read");//                continue;//            }//            sprintf(TmpCharBuf,"MsgStruBuf.LineNo =[%d]\n",MsgStruBuf.LineNo);//                MyTracePrint(TmpCharBuf);//            /*读取报文长度*///               if(readn(CPDout[0],MsgStruBuf.MText,10)<=0){//                   sprintf(TmpCharBuf,"read pipeSerToCpd[0] err(1) ,errno=[%d]",errno);//                MyTracePrint(TmpCharBuf);//                perror("read");//                continue;//            }//            MsgLen=atoi(MsgStruBuf.MText);//            sprintf(TmpCharBuf,"MsgLen =[%d]\n",MsgLen);//                MyTracePrint(TmpCharBuf);            /*读取管道文件*/            if(read(CPDout[0],&MsgpipeBuf,sizeof(WhMsgpipeBuf))<=0){                   sprintf(TmpCharBuf,"read pipeSerToCpd[0] err(1) ,errno=[%d]",errno);                MyTracePrint(TmpCharBuf);                perror("read");                exit(4);            }            sprintf(TmpCharBuf,"read pipe succ\n");                MyTracePrint(TmpCharBuf);                /*打开文件*/                fp1=fopen(MsgpipeBuf.filename,"r");                if(fp1 == NULL){                    sprintf(TmpCharBuf,"open file err\n");                        MyTracePrint(TmpCharBuf);                        continue;                                }                /*取得文件描述符号*/                lockfd = fileno(fp1);                 write_lock(lockfd);                memset(MsgStruBuf.MText,0,sizeof(MsgStruBuf.MText));                fseek(fp1,0L,0);                fread(MsgStruBuf.MText,MsgpipeBuf.MTextLen,1,fp1);                un_lock(lockfd);                fclose(fp1);                                        MsgLen = strlen(MsgStruBuf.MText);                //ii                ii = MsgpipeBuf.LineNo;                fp=fopen(CpdTraceFile,"a+");                //记录日志                if(fp != NULL) {                    getdatetimes(TmpCharBuf,1);                    fprintf(fp,"\nTran Send time is [%s]!",TmpCharBuf);                    MyTracePrint(TmpCharBuf);                    fprintf(fp,"\noutpkg is [%s]!\n",MsgStruBuf.MText);                    fprintf(fp,"\nMsgLen is [%d]!\n",MsgLen);                    fclose(fp);            }                    //发送,实际发送的信息长度                   Error = writen(ServerInfo[ii].Sock,MsgStruBuf.MText,MsgLen);                   if(Error < MsgLen) {                       sprintf(TmpCharBuf,"write to socket err(1) ,Error=[%d],errno=[%d]",Error,errno);                    MyTracePrint(TmpCharBuf);                    CloseSocket(ii);                   }else{                           sprintf(TmpCharBuf,"write to socket len=[%d]\n",Error);                        MyTracePrint(TmpCharBuf);                                              }            //                   CloseSocket(ii);        }        //判断当前socket状态是否正常,如果不正常则close掉        for(ii=0;ii<NowSocketNum;ii++) {            if(FD_ISSET(ServerInfo[ii].Sock,&rs)){                if(ServerInfo[ii].CurrStatus){//没有关闭                    nLen=sizeof(Error);                    //获取待处理错误并清除                    if((getsockopt(ServerInfo[ii].Sock,SOL_SOCKET,SO_ERROR,(void *)&Error,(int *)&nLen)==-1)){                        sprintf(TmpCharBuf,"socket status err(1) LineNo=[%d],errno=[%d]",ii,errno);                        MyTracePrint(TmpCharBuf);                        CloseSocket(ii);                        continue;                    }                    if(Error != 0){                        CloseSocket(ii);                        sprintf(TmpCharBuf,"socket status err(2) LineNo=[%d],errno=[%d]",ii,errno);                        MyTracePrint(TmpCharBuf);                        continue;                    }                                    }            }        }        //将当前socket设置为accpet状态的socket,并将状态改为1,应该是说现在是可接收数据状态        for(ii=0;ii<NowSocketNum;ii++) {            if(FD_ISSET(ServerInfo[ii].LsnSock,&rs)){                TmpSock=AcceptAndCheckIp(ServerInfo[ii].LsnSock);                if(TmpSock>=0)                {                    if(ServerInfo[ii].CurrStatus)                        CloseSocket(ii);                                        ServerInfo[ii].Sock = TmpSock;                                        sprintf(TmpCharBuf,"Accept succ LineNo=[%d],TmpSock=[%d]",ii,TmpSock);                    MyTracePrint(TmpCharBuf);                                        if(ServerInfo[ii].Sock>MaxFd)                        MaxFd= ServerInfo[ii].Sock;                    Flag = fcntl(ServerInfo[ii].Sock,F_GETFL,0);                    fcntl(ServerInfo[ii].Sock,F_SETFL,Flag|O_NONBLOCK);                    FD_SET(ServerInfo[ii].Sock,&rset);                    ServerInfo[ii].CurrStatus = 1;                }                                }        }        //根据Server的状态,读取发送来的信息        for(ii=0;ii<NowSocketNum;ii++) {            if(ServerInfo[ii].CurrStatus){                if(FD_ISSET(ServerInfo[ii].Sock,&rs)){                    memset(buf,0,sizeof(buf));                    //读取数据                    Len = readn(ServerInfo[ii].Sock,buf,10);                    if(Len<2&&Len>=0){                        sprintf(TmpCharBuf,"read socket err(1) LineNo=[%d],errno=%d",ii,errno);                        MyTracePrint(TmpCharBuf);                        CloseSocket(ii);                        continue;                    }else if(Len < 0&&Len != EWOULDBLOCK){                        sprintf(TmpCharBuf,"read socket err(2) LineNo=[%d],errno=%d",ii,errno);                        MyTracePrint(TmpCharBuf);                        CloseSocket(ii);                        continue;                    }                    MsgLen = atoi(buf);                    sprintf(TmpCharBuf,"MsgLen=[%d]\n",MsgLen);//                    MyTracePrint(TmpCharBuf);                    //报文长度                    if(MsgLen <= 0){                        sprintf(TmpCharBuf,"read socket err(3) LineNo=[%d],MsgLen=[%d]",ii,MsgLen);                        MyTracePrint(TmpCharBuf);                        CloseSocket(ii);                        continue;                    }else{                        //开始读取报文体                        Len = readn(ServerInfo[ii].Sock,buf+10,MsgLen);                        if(Len < 0&& Len != EWOULDBLOCK){                            sprintf(TmpCharBuf,"read socket err(4) LineNo=[%d],MsgLen=[%d]",ii,MsgLen);                            MyTracePrint(TmpCharBuf);                            CloseSocket(ii);                            continue;                        }else if(Len < MsgLen&&Len > 0){                            sprintf(TmpCharBuf,"read socket err(5) LineNo=[%d],MsgLen=[%d]",ii,MsgLen);                            MyTracePrint(TmpCharBuf);                            CloseSocket(ii);                            continue;                        }                    }                     /*记录CPD交易日志*/                    fp=fopen(CpdTraceFile,"a+");                    if(fp != NULL) {                        getdatetimes(TmpCharBuf,1);                        fprintf(fp,"\nTran receive time is [%s]!",TmpCharBuf);                        fprintf(fp,"\npkg is [%s]!\n",buf);                        fflush(fp);                        fclose(fp);                    }                                    memset(&MsgStruBuf,0,sizeof(MsgStruBuf));                        MsgStruBuf.Mtype=atoi(g_MY_IN_TYPE);                    //确定具体为哪一个socket                    MsgStruBuf.LineNo = ii;                    MsgStruBuf.MTextLen=MsgLen+10;                    //将接收到的信息放到MsgStruBuf.MText中                    memcpy(MsgStruBuf.MText,buf,MsgLen);                    sprintf(TmpCharBuf,"MsgStruBuf.Mtype=[%d]\n,MsgStruBuf.MTextLen=[%d]\n",MsgStruBuf.Mtype,MsgStruBuf.MTextLen);                    MyTracePrint(TmpCharBuf);                    sprintf(TmpCharBuf,"MsgStruBuf.MText = [%s] msgQid_in=[%d]\n",MsgStruBuf.MText,msgQid_in);                    MyTracePrint(TmpCharBuf);                    //给消息队列发送信息                    WkErr=msgsnd(msgQid_in,&MsgStruBuf,MsgLen+sizeof(int)*2+sizeof(long),0);                        if(WkErr){                            sprintf(TmpCharBuf,"WkErr=[%d]\n",WkErr);                        MyTracePrint(TmpCharBuf);                        perror("msgsnd");                        }                                                    /*WkErr=MyMsgQSend(msgQid_in,&MsgStruBuf);*/                }            }        }    }} 




[解决办法]
将NowSocketNum = 1; //当前socket数目
定义大一点。最好是收到一个连接请求后fork一个进程或是pthread_create一个线程去处理。
[解决办法]
我就不懂了,标记一下有错吗?我在研究这块内容,标记一下以后用,你干嘛一次次给我删除,哪个管理员干的,我就想知道这怎么就违法还是什么啊
[解决办法]
简单看了下代码(C不是很熟),感觉从需求来说,服务端应该是支持多线程或多进程,为每个连接客户开启单独的socket连接服务。如“gyj_china”所言......

热点排行