C ++聊天系统

时间:2015-07-06 17:47:50

标签: c++ multithreading sockets chat

我能够连接客户端和服务器,但不能互相聊天。我只能让服务器接收消息而客户端只能发送消息......但它没有相反的工作方式。

相关服务器代码:

    while(recv(acceptedSocket,buffer,255,0)){
        std::cout << buffer << std::endl;
        memset(buffer,0,sizeof(buffer));
        n = send(acceptedSocket,"Message received!", 18 , 0);
        if(n < 0)
            error("Failed sending data!");
    }

相关客户代码:

    do{
        memset(buffer,0,sizeof(buffer));
        std::cout << "Enter your message: " << std::endl;
        std::cin.getline(buffer,255);
        n = send(connectingSocket,buffer,strlen(buffer),0);
    } while(n > 0);

我可以让服务器和客户端在没有多线程的情况下发送和接收消息,还是需要多线程?

所有代码 服务器

    int main() {

        int listeningSocket,acceptedSocket,port,n;
        unsigned int clientLength;
        char buffer[256];
        struct sockaddr_in server_address , client_address;
        std::cout << "ENTER PORT(ABOVE 2000):";
        std::cin >> port;
        if(port < 2000){
            error("NO PORT PROVIDED");
        }
        listeningSocket = socket(AF_INET,SOCK_STREAM,0);
        if(listeningSocket < 0)
            error("FAILED CREATING A SOCKET!");
        memset((char * ) &server_address,0,sizeof(server_address));
        server_address.sin_family = AF_INET;
        server_address.sin_addr.s_addr = INADDR_ANY;
        server_address.sin_port = htons(port);
        if(bind(listeningSocket,(struct sockaddr *) &server_address,sizeof(server_address)) < 0)
            error("BINDING FAILED!");
        listen(listeningSocket,5);
        clientLength = sizeof(client_address);
        acceptedSocket = accept(listeningSocket,(struct sockaddr *) &client_address,&clientLength);
        if(acceptedSocket < 0)
            error("ACCEPTING FAILED!");
        std::cout << "Connection incoming from " << client_address.sin_addr.s_addr << std::endl;
        while(recv(acceptedSocket,buffer,255,0)){
            std::cout << buffer << std::endl;
            memset(buffer,0,sizeof(buffer));
            n = send(acceptedSocket,"Message received!", 18 , 0);
            if(n < 0)
                error("Failed sending data!");
        }
    }

客户端:

int main() {
    int connectingSocket,portNo,n;
    struct sockaddr_in server_address;
    struct hostent *server;
    char buffer[256];
    std::cout << "Enter server's IP:";
    char * ipHolder;
    std::cin >> ipHolder;
    server = gethostbyname(ipHolder);
    if(server == NULL){
        error("NO SUCH HOST!");
    }
    std::cout << "ENTER PORT:";
    std::cin >> portNo;
    connectingSocket = socket(AF_INET,SOCK_STREAM,0);
    if(connectingSocket < 0)
        error("FAILED OPENING A SOCKET!");
    memset(&server_address,0,sizeof(server_address));
    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(portNo);
    memcpy(server->h_addr_list,&server_address.sin_addr.s_addr,server->h_length);
    if(connect(connectingSocket,(sockaddr *)&server_address,sizeof(server_address)) < 0)
        error("CONNECTION FAILURE!");
    std::cout << "CONNECTION MADE!" << std::endl;
    std::cin.ignore();
    do{
        memset(buffer,0,sizeof(buffer));
        std::cout << "Enter your message: " << std::endl;
        std::cin.getline(buffer,255);
        n = send(connectingSocket,buffer,strlen(buffer),0);
    }while(n > 0);

    return 0;
 }

谢谢!

2 个答案:

答案 0 :(得分:0)

最简单最直接的解决方案是让服务器/客户端发送消息,然后让它等待另一方的回复,如:

服务器:

while(recv(acceptedSocket,buffer,255,0)){  //here you read a message
        std::cout << "clients message: " << buffer << std::endl;  //print it on screen
        memset(buffer,0,sizeof(buffer));
        /*
             instead of sending "message recieved" to server, try to get
             some message from the user using cin maybe
             and send() what the user has entered
             then loop over and get another message
        */
        std::cin.getline(buffer,255); //get user's message
        //don't forget to find out buffer length
        n = send(acceptedSocket, buffer, buffer_len , 0); //send the message
        if(n < 0)
            error("Failed sending data!");
        //client has got the message now, you loop and wait for his reply
    }

客户端:

do{
        memset(buffer,0,sizeof(buffer));
        std::cout << "Enter your message: " << std::endl;
        std::cin.getline(buffer,255);  //get message
        n = send(connectingSocket,buffer,strlen(buffer),0); //send it to server
        /*
            recv() from the connecting socket and print the message
            when you loop over, the server has your message, user enters 
            another one, and the client waits for the message, and then 
            sends something the user entered
        */
        recv(connectingSocket,buffer,255,0); //wait for server's user reply
        std::cout << "server's message: " << buffer << std::endl;
        //you have now recieved server's message, you loop over and you're ready to send his another one
    } while(n > 0);

所以这样,你必须等待回复,你不能连续发送2(+)条消息。

我没有对此进行过测试,但它对它的外观大概有点了:)

答案 1 :(得分:0)

我做了两个不同的程序,它可以在同一台计算机上运行,​​也可以在网络上运行...

玩得开心......这就是我的开始......看着你的,有很多顾虑......所以切断过去玩这个服务器和客户端。

//Echo Server and Client using Berkley Socket Primitives
// Server
#include <sys/socket.h>
#include <netinet/in.h>

int main (int argc, const char * argv[]) {

  char                         buffer[128]; 
  int                           sinlen;
  struct sockaddr_in    sin; 
  int                           s, h; 

  sin.sin_family = AF_INET; 
  sin.sin_addr.s_addr = INADDR_ANY;
  sin.sin_port = htons(888);   // Port 888
                                         // SOCK_STREAM is TCP
  s = socket(AF_INET, SOCK_STREAM,0);
                                        // Bind socket to local port
  bind(s,(struct sockaddr*)&sin,sizeof(sin));
                                        // Listen for 1 connection
  listen(s,1);
  sinlen = sizeof(sin);      
                                        // 1. Block for connection
  h=accept(s,(struct sockaddr*)&sin,&sinlen );
                                        // 2. Block for receive
  recv(h,buffer,sizeof(buffer),0); 
                                        // 3. Echo received data
  send(h,buffer,strlen(buffer),0);

  close(h);

  return 0;
}



// Client
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

int main (int argc, const char * argv[]) {

  char                         buffer[128]= "Hello world"; 
  struct sockaddr_in      sin; 
  struct hostent           *host; 
  int                           s; 

  host = gethostbyname("localhost");  

  memcpy(&(sin.sin_addr), host->h_addr,host->h_length); 
  sin.sin_family = host->h_addrtype; 
  sin.sin_port = htons(888);
                                               // Create socket port 888
  s = socket(AF_INET, SOCK_STREAM,0);
                                               // 1. Block for server accept
  connect(s,  (struct sockaddr*)&sin,sizeof(sin));     
                                               // 2. Send "Hello world"       
  send(s,buffer,strlen(buffer)+1,0);   
                                               // 3. Block for receive 
  recv(s,buffer,sizeof(buffer),0);
                                               // Print received data
  NSLog(@"Received %s\n",buffer); 

  close(s);

  return 0;
}
相关问题