1. 程式人生 > 其它 >用c++語言socket庫函式實現服務端客戶端聊天室

用c++語言socket庫函式實現服務端客戶端聊天室

客戶端

/*
 * 程式名:client.cpp,此程式用於演示socket的客戶端
 * 作者:C語言技術網(www.freecplus.net) 日期:20190525
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
 
int
main(int argc,char *argv[]) { if (argc!=3) { printf("Using:./client ip port\nExample:./client 127.0.0.1 5005\n\n"); return -1; } // 第1步:建立客戶端的socket。 int sockfd; if ( (sockfd = socket(AF_INET,SOCK_STREAM,0))==-1) { perror("socket"); return -1; } // 第2步:向伺服器發起連線請求。 struct hostent* h;
if ( (h = gethostbyname(argv[1])) == 0 ) // 指定服務端的ip地址。 { printf("gethostbyname failed.\n"); close(sockfd); return -1; } struct sockaddr_in servaddr; memset(&servaddr,0,sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(atoi(argv[2])); // 指定服務端的通訊埠。 memcpy(&servaddr.sin_addr,h->h_addr,h->h_length);
if (connect(sockfd, (struct sockaddr *)&servaddr,sizeof(servaddr)) != 0) // 向服務端發起連線清求。 { perror("connect"); close(sockfd); return -1; } char buffer[1024]; // 第3步:與服務端通訊,傳送一個報文後等待回覆,然後再發下一個報文。 while(1) { int iret,i; memset(buffer,0,sizeof(buffer)); printf("請輸入你要傳送的訊息:"); scanf("%s",buffer); // sprintf(buffer,"這是第%d個超級女生,編號%03d。",ii+1,ii+1); if ( (iret=send(sockfd,buffer,strlen(buffer),0))<=0) // 向服務端傳送請求報文。 { perror("send"); break; } printf("傳送:%s\n",buffer); memset(buffer,0,sizeof(buffer)); if ( (iret=recv(sockfd,buffer,sizeof(buffer),0))<=0) // 接收服務端的迴應報文。 { printf("iret=%d\n",iret); break; } printf("接收:%s\n",buffer); } // 第4步:關閉socket,釋放資源。 close(sockfd); }

服務端

/*
 * 程式名:server.cpp,此程式用於演示socket通訊的服務端
 * 作者:C語言技術網(www.freecplus.net) 日期:20190525
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
 
int main(int argc,char *argv[])
{
  if (argc!=2)
  {
    printf("Using:./server port\nExample:./server 5005\n\n"); return -1;
  }
 
  // 第1步:建立服務端的socket。
  int listenfd;
  if ( (listenfd = socket(AF_INET,SOCK_STREAM,0))==-1) { perror("socket"); return -1; }
 
  // 第2步:把服務端用於通訊的地址和埠繫結到socket上。
  struct sockaddr_in servaddr;    // 服務端地址資訊的資料結構。
  memset(&servaddr,0,sizeof(servaddr));
  servaddr.sin_family = AF_INET;  // 協議族,在socket程式設計中只能是AF_INET。
  servaddr.sin_addr.s_addr = htonl(INADDR_ANY);          // 任意ip地址。
  //servaddr.sin_addr.s_addr = inet_addr("192.168.190.134"); // 指定ip地址。
  servaddr.sin_port = htons(atoi(argv[1]));  // 指定通訊埠。
  if (bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) != 0 )
  { perror("bind"); close(listenfd); return -1; }
 
  // 第3步:把socket設定為監聽模式。
  if (listen(listenfd,5) != 0 ) { perror("listen"); close(listenfd); return -1; }
 
  // 第4步:接受客戶端的連線。
  int  clientfd;                  // 客戶端的socket。
  int  socklen=sizeof(struct sockaddr_in); // struct sockaddr_in的大小
  struct sockaddr_in clientaddr;  // 客戶端的地址資訊。
  clientfd=accept(listenfd,(struct sockaddr *)&clientaddr,(socklen_t*)&socklen);
  printf("客戶端(%s)已連線。\n",inet_ntoa(clientaddr.sin_addr));
 
  // 第5步:與客戶端通訊,接收客戶端發過來的報文後,回覆ok。
  char buffer[1024];
  char byebye[1024];
  while (byebye!="bye")
  {
    
    int iret;
    memset(buffer,0,sizeof(buffer));
    if ( (iret=recv(clientfd,buffer,sizeof(buffer),0))<=0) // 接收客戶端的請求報文。
    {
       printf("iret=%d\n",iret); break;  
    }
    printf("接收:%s\n",buffer);

    strcpy(byebye,buffer);

//    char byebye = 'bye';
    if(byebye[0] == 'b' && byebye[1]=='y' && byebye[2]=='e')
    {
        printf("聊天結束\n");
        break;
        return -1;
    }
    


     printf("我已收到你的訊息,下面是我對你的回覆\n");
    scanf("%s",buffer);
//    strcpy(buffer,"ok");
    if ( (iret=send(clientfd,buffer,strlen(buffer),0))<=0) // 向客戶端傳送響應結果。
    { perror("send"); break; }
    printf("傳送:%s,\n",buffer);
    
    

  }
 
  // 第6步:關閉socket,釋放資源。
  close(listenfd); close(clientfd);
}

事件效果

來源:www.freecplus.net