C -在服务器和客户端(Linux)之间创建无尽的套接字连接



我用C创建了一个简单的套接字程序(使用Ubuntu),连接工作正常,服务器编译和客户端提供IP和端口号。

但连接建立后,客户端只能访问send one message,然后访问connection closes。当客户端发送消息时,服务器接收消息,程序ends by itself

我试图使用while loop,但它给了我一个Error on binding。是否有办法使其无限,以便当用户输入exit或某些specific key/command时,程序结束。

server.c更新了WHILE LOOP

#include<stdio.h>  
#include<stdlib.h>  
#include<sys/types.h>     
#include<sys/socket.h>  
#include<netinet/in.h>  
#include<string.h>  
int main(int argc, char *argv[])  
{  
      int sockfd, newsockfd, portNum, clien, n;
      char buffer[256];
      struct sockaddr_in serv_addr,cli_addr;
  if (argc < 2)
  {
        fprintf(stderr, "nno port provided");
        exit(1);
  }
  sockfd = socket(AF_INET,SOCK_STREAM, 0);
  if (sockfd < 0)
        printf("nprovide a valid port numbern");
  bzero((char *)&serv_addr, sizeof(serv_addr));
  portNum = atoi(argv[1]);
  serv_addr.sin_family = AF_INET;
  serv_addr.sin_addr.s_addr = INADDR_ANY;
  serv_addr.sin_port = htons(portNum);
  if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0 )
        printf("error on binding");
  while(1)
  {
       listen(sockfd,5);
  }
  clien = sizeof(cli_addr);
  newsockfd=accept(sockfd, (struct sockaddr *) &cli_addr, &clien );
  if (newsockfd < 0)
        printf("=> Error on accepting...n");
  bzero(buffer, 256);  
  n = read(newsockfd, buffer, 256); 
  if (n < 0)  
        printf("error reading from socket...n");
  printf("%sn", buffer);
  n = write(newsockfd, "message received.", 58);
  if (n < 0)
        printf("cannot write from socket...n");
  return 0;
}

client.c更新了WHILE LOOP

#include<stdio.h>  
#include<stdlib.h>  
#include<sys/types.h>     
#include<sys/socket.h>  
#include<netinet/in.h>  
#include<netdb.h>  
#include<string.h>  
int main(int argc, char *argv[])  
{  
      int sockfd,portno,n;
      char buffer[256];
      struct sockaddr_in serv_addr;
      struct hostent *server;
      //while(counter != 5)
      // /{
            if (argc < 3)
      {  
            fprintf(stderr,"Usage %s hostname port...n",argv[0]);
            exit(1);
      }
      portno = atoi(argv[2]);
      sockfd = socket(AF_INET, SOCK_STREAM, 0);
      if (sockfd < 0)
            printf("error opening socket...n");
      bzero((char *) &serv_addr, sizeof(serv_addr));
      server = gethostbyname(argv[1]);
      if (server == NULL)
      {
            fprintf(stderr,"no such host...n");
            exit(0);
      }
      serv_addr.sin_family = AF_INET;
      bcopy((char *)server->h_addr,(char *)&serv_addr.sin_addr.s_addr,server->h_length);
      serv_addr.sin_port = htons(portno);
      if (connect(sockfd, &serv_addr,sizeof(serv_addr)) <0 )  
            printf("error connectingn");
      printf("your message:");
      fgets(buffer, 256, stdin);
      while(1)
      {
            n = write(sockfd,buffer,strlen(buffer));
      }
      if (n < 0)
            printf("error writing to socketn");
      n = read(sockfd, buffer, 255);
      if (n < 0)
            printf("error reading from socketn");
      printf("%sn", buffer);          
      return 0;
}

谢谢。

服务器的问题是,只要收到消息,就会立即终止。您应该做的是使用recv()函数继续侦听,直到客户端断开连接。这里有一段代码应该可以做到这一点。

免责声明:然而,我还没有测试过它,它是从一个旧的项目,我修改了你在飞行它应该工作,但我不是100%肯定,我没有时间测试它现在,但随时问问题,如果有什么错误,我会尽量纠正它。

编辑:尝试重新绑定会导致错误,因为绑定已经完成,端口已经很忙,所以你不能"分配"其他程序到这个端口,因此给你一个错误。您唯一要做的就是确保您的服务器一直侦听,直到客户端与服务器断开连接。

同样,有些代码可能是为c++编写的,但是网络部分应该工作得很好。

如果您有问题,请随意尝试并评论。Server.c:

    int socket_desc , client_sock , c , *new_sock;
    struct sockaddr_in server , client;
    socket_desc = socket(AF_INET , SOCK_STREAM , 0);
    if (socket_desc == -1)
    {
        //HANDLE ERROR
    }
    printf("Socket createdn");
    //Prepare the sockaddr_in structure
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons( 8000 );
    //Binding, you already do it correctly.
    if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server))< 0)
    {
        //ERROR
    }
    printf("bind done");
    //Listen
    listen(socket_desc , 3);
    printf("Waiting for incoming connections...");
    c = sizeof(struct sockaddr_in);

    while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) )
    {
        puts("Connection accepted");
        pthread_t sniffer_thread;
        new_sock = (int*) malloc(1);
        *new_sock = client_sock;
        if( pthread_create( &sniffer_thread , NULL ,  connection_handler , (void*) new_sock) < 0)
        {
            //ERROR
        }
        printf("Handler assigned");
    }
    if (client_sock < 0)
    {
        //ERROR
    }
    //return 0;
}
/*
 * This will handle connection for each client you may have and read indefinitely
 * */
void *connection_handler(void *socket_desc)
{
    //Get the socket descriptor
    int sock = *(int*)socket_desc;
    int read_size;
    char *message , client_message[2000];
    string smatrix ;
    int ind ;
    string tok ;
    int i = 0 ;

    //Receive a message from client
    while( (read_size = recv(sock , client_message , 2000 , 0)) > 0 )
    {
        //What you want to do with the client's message
    }
    if(read_size == 0)
    {
        printf("Client disconnected");
        fflush(stdout);
    }
    else if(read_size == -1)
    {
        //ERROR
    }
    //Free the socket pointer
    free(socket_desc);

对于客户端,执行while循环,直到经过一定时间或输入给定的字符或值。比如:

while(wantToExit == false){
   char a;
   printf("Please enter a char");
   scanf("%c", &a);
   write(sock , a , 1); //Note use strlen() for strings
}

希望有所帮助

您实际期望服务器做什么?你打开/阅读/终止。当然,终止会隐式地关闭套接字——幸运的是,您忘记显式地关闭了。

必须不断地从套接字读取。不知道你说的"它"是什么意思。给我一个绑定错误";如果你试图重新绑定,那当然是错误的。你不会一次又一次地打开一个文件,然后……读取它的数据。

如果您想在套接字从另一端关闭后侦听它,只需将listen置于外部循环中。

阅读维基百科关于套接字的基础知识,并检查链接。

最新更新