求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语言不是太懂,发出来大家给看下,到底是哪里出了问题,这个问题一直没有解决,非常郁闷。
#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);*/ } } } }}