通信:将消息从客户端发送到服务器

时间:2018-11-21 17:52:03

标签: c linux sockets tcp

“我的服务器”可以一次处理多个客户端/交换机。

我的问题是我相信在交换机中,我正在尝试向控制器发送开放消息。我在交换机中创建tcp套接字,然后在尝试将消息发送到控制器后立即创建,但是当我尝试这样做时,套接字与控制器断开连接并进入无限循环。我不确定为什么在我的while循环之外创建和发送消息时会发生这种情况。如果我在发送消息的位置进行注释,则套接字将保持与控制器的连接,并且能够等待一组文件描述符中的一个可以执行I / O,目前,我只有键盘和套接字。连接控制器时,我的套接字还会收到来自控制器的消息“您已连接到服务器”。另外,由于我的开关插座已断开连接,因此我的recv()返回错误代码107。

我不确定是否提供了太多的代码来浏览,但是在我认为我的错误在交换机和控制器中都发生的地方添加了注释。非常感谢您的帮助。我没有添加任何自己的头文件,因为它们没有必要。


这是我执行切换的地方。在此处发送和接收消息。

#include "switch.h"
#include "openFIFO.h"
#include "packets.h"

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

#include <sys/socket.h>
#include <sys/types.h>
#include <sys/select.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include<poll.h>
#include <signal.h>
void do_switch(int swIport, char *trafficfile,int swJport, int swKport, int IPlow, int IPhigh,char serverAddress[256], unsigned short portNumber){

 int  switch_sock;
 char server_response[256]; 
 struct pollfd pfds[6];
 int rval;
/* Switch */
Switch sw;
sw.swJport = swJport;
sw.swIport = swIport;
sw.swKport = swKport;
sw.IPlow = IPlow;
sw.IPhigh = IPhigh;
int switchLength = sizeof(Switch);

 // printf("\n\nstruct switchLength: %d\n", switchLength);
//  printf("\n\nSwitch Struct: swIport: %d, swJport: %d,  swKport: %d, 
    IPlow: %d, IPhigh: %d\n", sw.swIport, sw.swJport, sw.swKport, sw.IPlow, 
    sw.IPhigh);

   printf("\n\nSwitch created with the following: swIport: %d, trafficfile: 
   %s, swJport: %d,  swKport: %d, IPlow: %d, IPhigh: %d, serverAddress: %s, 
   portNumber: %d\n", swIport, trafficfile, swJport, swKport, IPlow, IPhigh, 
   serverAddress, portNumber);


int fifoWrite[2];
int fifoRead[2];
int counter = 0;
char message[20] = "Hello";

/* Create fifos */
if(swJport != -1){
        fifoWrite[0] = openWF(swIport,swJport);
        fifoRead[0] = openReadFifo(swJport, swIport);
    counter = counter + 2;
}
if(swKport != -1){
    fifoWrite[1] = openWF(swIport,swKport);
        fifoRead[1] = openReadFifo(swKport, swIport);
    counter = counter + 2;
}else if(swKport == -1){
    fifoWrite[0] = openWF(swIport,swKport);
    fifoRead[0] = openReadFifo(swKport, swIport);
    counter = counter + 2;
}

printf("fifoWrite[0]: %d\n", fifoWrite[0]);
printf("fifoRead[0]: %d\n", fifoRead[0]);
printf("fifoWrite[1]: %d\n", fifoWrite[1]);
printf("fifoRead[1]: %d\n", fifoRead[1]);   


/* Establish connection between the controller and switch */
/* Send a open packet to the controller */
/* Sending a stuct */

 //PROBELM HERE BELOW!!!!!!!

 switch_sock = CreateTCPClientSocket(portNumber, serverAddress);    
 if(send(switch_sock, message, sizeof(message), 0) == -1){
    fprintf(stderr, "Send() Failed");
 }
 else{
   printf("Open packet is being sent to the controller\n");
 }


/* Initialize poll parameters */
//Keyboard
pfds[0].fd = STDIN_FILENO;
pfds[0].events = POLLIN;

//  Socket!
pfds[1].fd = switch_sock;
pfds[1].events = POLLIN;


printf("Starting switch............................\n\n");

while(1){

    rval = poll(pfds,2,-1);
    if(rval == 0){
        fprintf(stderr, "Poll timed out. \n");
    }if(rval == -1){
        fprintf(stderr, "ERROR: poll() failed");
        exit(0);
    }


    /* Check Keyboard */
    if(pfds[0].revents & POLLIN && pfds[0].fd == 0){
               int a;
               char command[1024][256];
               int commands;
               char buf[256];
               commands = read(0, buf, 256);
               buf[commands] = '\0';
               buf[commands] = '\0';

               char *token;
               token = strtok(buf, " ");
               while(token != NULL){
                       strcpy(command[a], token);
                       a++;
                       token = strtok(NULL, " ");
               }
               a = 0;
               bzero(buf, 256);

               if(strcmp(command[0], "list") == 0){
                        //TODO: Make a print function
                       printf("print_switch()\n");
               }
               if(strcmp(command[0], "exit") == 0){
                       //TODO: Make a print function
                    printf(" print_switch()\n");
                                printf("switch-disconnected\n");
                                close(switch_sock);
                                exit(0)

              }
      }

    /* Server sent a welcome message */
    // Might be PROBELM HERE BELOW when trying to send the initial packet to 
       controller!!!!!!!
    if(pfds[1].revents & POLLIN){
        recv(switch_sock, &server_response, sizeof(server_response), 0);
        printf("%s\n", server_response);    
    }
 }
}

为交换机创建一个TCP套接字。

int CreateTCPClientSocket( unsigned short port, char *serverAddress){
  int sock; /*socket to create */
  struct sockaddr_in servAddr; /* Local address */

  /* Construct local address structure */   
  /* Create socket for incoming connections */
  if ((sock =  socket(AF_INET, SOCK_STREAM, 0)) < 0){
            fprintf(stderr,"ERROR: socket() failed\n");
            exit(0);
    }

  memset(&servAddr, 0, sizeof(servAddr));
  servAddr.sin_family = AF_INET;
  servAddr.sin_port = htons(port);
  servAddr.sin_addr.s_addr = inet_addr(serverAddress);

  if(connect(sock, (struct sockaddr *)&servAddr, sizeof(struct sockaddr)) < 
  0){
     printf("Error code: %d\n", errno);
     fprintf(stderr, "ERROR: connect() just failed\n");
     exit(0);   
 }
 return sock;
}


这是控制器

#include "controller.h"
#include "packets.h"
#include "switch.h"
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

#include <sys/socket.h>
#include <sys/types.h>
#include <sys/select.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>

void do_controller(int nSwitch, int portNumber){

   int controller_sock; /* Socket descriptor for server/controller */
   int clnSocket;  /*Socket descriptor for clients */
   int activity;
   int max_sd;
   int sd;
   int client_socket[nSwitch];

   struct sockaddr_in address;
   int addrlen;
   /* Controller stuff */
   Controller cont;
   cont.ackCounter = 0;
   cont.openCounter = 0;

   Switch sw;

  char message[256] = "You have reached the server\n";
  char recv_message[20];

   printf("\n\nController created: nSwitch: %d on portNumber: %d\n", nSwitch, portNumber);

  /* Initialise all client_socket[] to 0 so not checked */
  for(int i = 0; i < nSwitch; i++){
     client_socket[i] = 0;
  }

 /*Create the server/controller socket */
  controller_sock = CreateTCPServerSocket(portNumber);  
 //addrlen = sizeof(address);
 /* Prepare for nonblocking I/O polling/select from the controller socket */    
 printf("Starting server.........\n\n");
 while(1){
    /* Zero the socket set and set for server sockets */
    /* This must be reset every time select() is called */
    /* Add keyboard to descriptor */
    /* Add client and controller sockets  to set */

    FD_ZERO(&sockSet);
    FD_SET(STDIN_FILENO, &sockSet);
    FD_SET(controller_sock, &sockSet);
    max_sd = controller_sock;
    //max_sd = 0;
    printf("nSwitch: %d\n", nSwitch);   
    for(int x = 0; x < nSwitch; x++){
        sd = client_socket[x];
        printf("sd: %d\n\n", sd);
        if(sd > 0)
            FD_SET(sd, &sockSet);
        if(sd > max_sd)
            max_sd = sd;
    }   
    printf("max_sd: %d\n", max_sd);

    //wait for  one of the sockets, timeout is Null,
    //so wait indefinitely
    activity = select(max_sd + 1, &sockSet, NULL, NULL,NULL);
    //printf("Activity: %d\n", activity);
    if(activity < 0){
        fprintf(stderr, "ERROR: select()\n");
        exit(0);
    }

    /*Check keyboard */
    if(FD_ISSET(STDIN_FILENO, &sockSet)){
        int a;
        char command[1024][256];
        int commands;
        char buf[256];
        commands = read(0, buf, 256);
        buf[commands] = '\0';

        char *token;
        token = strtok(buf, " ");
        while(token != NULL){
            strcpy(command[a], token);
            a++;
            token = strtok(NULL, " ");
        }
        a = 0;  
        bzero(buf, 256);

        if(strcmp(command[0], "list") == 0){
            //TODO: Make a print function
            print_controller(&cont, nSwitch);
        }
        if(strcmp(command[0], "exit") == 0){
            //TODO: Make a print function
            print_controller(&cont, nSwitch);
            exit(0);
        }   
        continue;   
    }

    /* Check the incoming FIFOS from the controller an attached switches */
    /*If something happened on the controller socket,
      then its an incomming connection. Accept new communitcation.Wait for a client to connect.
      Recieve packets sent to the controller_sock
      */

    if(FD_ISSET(controller_sock, &sockSet)){

        clnSocket = AcceptTCPConnection(controller_sock);
        if(send(clnSocket, message, sizeof(message), 0) != sizeof(message)){
            fprintf(stderr, "Send()");
            exit(0);
        }
        puts("Welcome message sent successfuly");

        //PROBELM HERE BELOW!!!!!!! Returns error code 107 because the 
          socket disconnected.
        recv(controller_sock, &recv_message, sizeof(recv_message), 0);
        printf("This is my recv_message: %s\n", recv_message);

        /*add new socket to array of sockets*/
        for(int a = 0; a < nSwitch; a++){
            /*if position is empty */
            if(client_socket[a] == 0){
                client_socket[a] = clnSocket;
                printf("Adding to list of sockets as %d\n", client_socket[a]);  
                break;  
            }
        }                           
    }

    /* Communicate with the sockets and handle TCP Client */
    for(int z = 0; z <nSwitch; z++){
        sd = client_socket[z];
        /*Check if it was socket closed, and do other stuff */
        if(FD_ISSET(sd ,&sockSet )){
            getpeername(sd , (struct sockaddr*)&address , (socklen_t*)&addrlen); 
            printf("Host disconnected , ip %s , port %d \n" , inet_ntoa(address.sin_addr) , ntohs(address.sin_port));    
            close( sd );   
                        client_socket[z] = 0;
        }else{
            //Do stuff for the client        
            printf("This is the client %d\n", sd);
        }
    }
}

}


这些是控制器的功能:将端口分配给套接字,将套接字设置为侦听

int AcceptTCPConnection(int servSock){
   int clntSock;                   /* Socket descriptor for client */
   unsigned int clientAddressLen;   /* sizeof(client_address); Length of client */
   struct sockaddr_in cli_addr; /* Client address */

   /* Set the size of the in-out parameter */
   clientAddressLen = sizeof(cli_addr);
   printf("ClientAddressLen: %x\n", clientAddressLen);
   /* Wait for a client to connect */
   if ((clntSock = accept(servSock, (struct sockaddr *) &cli_addr,  
   &clientAddressLen)) < 0){
         fprintf(stderr, "ERROR: accept failed\n");
         exit(0);
    }
   /* clntSock is connected to a client! */
   //infrom user of socket number used in send and receive commands
   printf("Handling client %s\n", inet_ntoa(cli_addr.sin_addr));
   printf("New connection: socket fd is: %d, ip is: %s, port: %d\n\n", 
   clntSock, inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port));
return clntSock;

}


创建一个TCP套接字

int CreateTCPServerSocket(unsigned short port){
   int sock; /* socket to create */
   struct sockaddr_in servAddr; /* Local address */

   /* Create socket for incoming connections */
     if ((sock =  socket(AF_INET, SOCK_STREAM, 0)) < 0){
       fprintf(stderr,"ERROR: socket() failed\n");
       exit(0);
     }

  /* Construct local address structure */
  /* Define the server address */
 //bzero((char *) &server_address, sizeof(server_address));

    memset(&servAddr, 0, sizeof(servAddr));   /* Zero out structure */
    servAddr.sin_family = AF_INET;                /* Internet address family 
   */
    servAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface 
  */
    servAddr.sin_port = htons(port);              /* Local port */

    /* Bind to the local address */
    printf("New connection:  ip is: %s, port: %d\n\n", 
    inet_ntoa(servAddr.sin_addr), ntohs(servAddr.sin_port));

    if (bind(sock, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0){
        printf("Error code: %d\n", errno);
        fprintf(stderr,"ERROR: bind() just failed\n");
        exit(0);
    }
    /* Mark the socket so it will listen for incoming connections */
    if (listen(sock, 5) < 0){
       fprintf(stderr,"ERROR: listen() failed\n");
       exit(0);
    }
    return sock;
 }

0 个答案:

没有答案