【问题标题】:Linux Socket /Segmentation FaultLinux 套接字/分段错误
【发布时间】:2015-07-21 03:37:58
【问题描述】:

我需要在 linux 中使用套接字发送数据。我使用套接字发送数据,使用管道接收数据。当我尝试在函数中发送数据时:SendGTSMessage,我将发送数据值设为空。 当我尝试在SendGTSMessage 中访问Bytessent 时,我也收到Segmentation fault 错误。

SendGTSMessage函数从HandleGtsMessage函数调用。

任何见解都会有所帮助,

void* BeginGTSServer(void* arg)
{
   char                 Buffer[1000];
   char                 *interface= NULL;
   unsigned short       port=DEFAULT_PORT;
   int                  retval;
   socklen_t                  fromlen;
   struct sockaddr_in   local;
   struct sockaddr_in  from;
   int                 listen_socket;
   int                  continueMsgs = 1;
   int                  errNumber;
   char                OutputString[255];

   local.sin_family = AF_INET;
  // local.sin_addr.s_addr = (!interface)?INADDR_ANY:inet_addr(interface);
   local.sin_addr.s_addr =INADDR_ANY;    
   local.sin_port = htons(port);

   listen_socket = socket(AF_INET,SOCK_STREAM,0); // TCP socket
   logMessage("Socket Created.\n");   

   if (listen_socket<0)
   {
      sprintf(OutputString,"*** socket() failed with error %d\n",errno);
      perror("Failed to create Socket");
      MsgBox("Failed To create Socket");
           // return;
   }
   if (bind(listen_socket,(struct sockaddr*)&local, sizeof(local)))
   {
      sprintf(OutputString,"*** bind() failed with error %d\n",errno);
      perror("bind() failed with error");
      MsgBox("bindfailed with error");
     // MessageBox(NULL, OutputString,"ERROR", MB_OK );
    //  return;
   }
   logMessage("Socket Binded.\n"); 
   if (listen(listen_socket,5) <0)
   {    
       sprintf(OutputString,"*** listen() failed with error %d\n",errno);
       perror("listen() failed with error");
       MsgBox("listen() failed with error");
      //MessageBox(NULL, OutputString,"ERROR", MB_OK );
      // return;
   }

logMessage("Listen Succeded.\n");  
fromlen =sizeof(from);   
glueDebug = true;
printf("listen_socket",listen_socket); 
msgsock =accept(listen_socket,(struct sockaddr *) &from, &fromlen);  
if (msgsock== -1)
{    
      sprintf(OutputString,"*** accept() error %d\n",errno);
      perror("accept() error");
      MsgBox("accept() error");
      //MessageBox(NULL, OutputString,"ERROR", MB_OK );
      // return;
}    
GTSConnected = true;
logMessage("GTS Connected.\n");
while( 1 )
{    
    retval = recv(msgsock,Buffer,sizeof(Buffer),0 );
    if (retval<0)
    {
        perror("Reading Stream Message Error");
        errNumber = errno;
        if (errno != ECONNREFUSED )
        {
            //fprintf(stderr,"*** recv() failed: error %d\n",errNumber);
        }
    }
    else
    {
         errNumber = 0;
    }
    if (retval == 0 || errNumber == ECONNREFUSED )
    {
         logMessage("GTS connection terminated.\n");
         MsgBox("GTS connection terminated.\n");
         // We are waiting for a connection.
         sprintf( GTSConnectionStatus, GTSNotConnected);
         GTSConnected = false;
         close(msgsock);
         msgsock = accept(listen_socket,(struct sockaddr*)&from,(socklen_t *) &fromlen);

         if (msgsock <0)
         {
            sprintf(OutputString,"*** accept() error %d\n",errno);
            MsgBox("accept() error");
            //MessageBox(NULL, OutputString,"ERROR", MB_OK );
            //return;
         }
         GTSConnected = true;
         continue;
      }
      // Null terminate the string.  Ignore the 0x85 at the end.
      Buffer[retval-1] = 0;
      logMessage("Buffer Message",&Buffer[4]);
      HandleGTSMessages(&Buffer[4]);
      logMessage("Message passed to handle function");
      continue;
   }
}

void HandleGTSMessages(char *Message)
{
   int loop;
   char LocalMsgBuffer[1024];
   char strippedMessage[1024];
//   char Message[1024];
   char *ProgramArgument[9] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
   logMessage("Program:%s\n",Message);       
   if (!strncmp(Message,"IsProgRunning",strlen("IsProgRunning")))
   {
      if (TstProgramConnected)
         sprintf(LocalMsgBuffer, "True:%s",executingVSProgram);
      else
         sprintf(LocalMsgBuffer, "False");

     SendGTSMessage(LocalMsgBuffer, strlen(LocalMsgBuffer), true);
     return;
   }
   else if (!strncmp(Message,"InfoRequest", strlen("InfoRequest")))
   {
      char hostname[255];
      char cwd[1024];
      char stationType[25];

      strcpy(hostname,"unknown");
      gethostname(hostname,254);
      getcwd( cwd, 1023 );
      strcpy(stationType,"Unknown");

      loop = 0;

      while (Station[loop].StationString[0] != 0)
      {
         if (FileExist(Station[loop].FileTest))
         {
            strcpy(stationType,Station[loop].StationString);
            break;
         }
         loop++;
      }
     sprintf(LocalMsgBuffertest,"Version: %s\n,HostName:%s\n,Execution Dir:%s\n,Station Type:%s",

     VERSION,hostname,cwd,stationType);
     logMessage("Info Request:%s\n",LocalMsgBuffertest);
     SendGTSMessage(LocalMsgBuffertest,strlen(LocalMsgBuffertest),true);
     return;
   }
}

int SendGTSMessage(char *MsgToSend, int msgLength, bool forceMsgExactly)
{
   char Buffer[1000];
   int bytesSent;
   int ShiftedMsgLength;
   struct hostent *hp;
   struct sockaddr_in server;
   char dum[40];

  /* local.sin_family = AF_INET;
     local.sin_addr.s_addr =INADDR_ANY;  
      local.sin_port = htons(port);

   sock=socket(AF_INET, SOCK_STREAM, 0);
   connect(sock,(struct sockaddr*)&local, sizeof(local));
   logMessage("connected with send gts",MsgToSend);
GTSConnected =true;*/

int sock;

sock = socket(AF_INET, SOCK_STREAM, 0);
char buffer[256];
char hostname[1024];

server.sin_family = AF_INET;
gethostname(hostname,sizeof(hostname));
hp = gethostbyname(hostname);
memcpy(&server.sin_addr,hp->h_addr,hp->h_length);
server.sin_port = htons(port);

connect(sock,(struct sockaddr *) &server,sizeof(server));
if (GTSConnected == true)
{
   // Overwrite the normal message, if we ran the crmvs program to disable 
   // or enable telemetry.
   if ((ExecutingBuiltInProgram) && (forceMsgExactly == false))    
   {
      HandleGTSMessages("ADV");
      if (strstr(MsgToSend,"PASSED"))
      // Advance the telemetry command.
         MsgToSend = BuiltInPassedMsg;
      else
         MsgToSend = BuiltInFailedMsg;

       msgLength = strlen (MsgToSend);    
      }

     // Copy in the msg to send, and terminate it with a 0x85.
     strncpy(&Buffer[4], MsgToSend, msgLength);
     // logMessage("Message Length  %s\n", msgLength);
     *(Buffer+msgLength+4) = (char)0x55;
     ShiftedMsgLength = (msgLength) << 8;
     memcpy(&Buffer[0], &ShiftedMsgLength, 4);
     *(Buffer) = (char)0xaa;

     bytesSent = send(sock,Buffer,msgLength+5,0);
     logMessage("Message Length  %s\n",Buffer);
     if (bytesSent <0)
     {
         // Just re-use the same buffer for the error message.
         sprintf(Buffer,"*** send() failed: error %d\n",strerror(errno));
         MsgBox("Send() Failed");
        // MessageBox(NULL, Buffer,"ERROR", MB_OK );
      }
   }
   //logMessage("Bytes Sent %s\n",bytesSent);
   // return bytesSent;*/
}

【问题讨论】:

标签: c linux sockets segmentation-fault


【解决方案1】:

sprintf(GTSConnectionStatus, GTSNotConnected);这不是使用 sprintf 的正确方法。

参考man page

【讨论】:

  • 虽然使用sprintf() 代替strcpy() 是不寻常且有些不安全的,但不一定不正确。没有GTSConnectionStatusGTSNotConnected 的声明可用,但是我们不能确定它是否正确。
  • 但可能导致分段错误
  • 可能导致段错误,但你无法知道它是否确实。你甚至没有解释它会在什么情况下起作用。在这种情况下,对问题发表评论是合理的,要求您提供做出此决定所需的信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多