1. 程式人生 > 實用技巧 >Linux下socket程式設計基礎1-初探(把服務端程式碼放到雲伺服器上)

Linux下socket程式設計基礎1-初探(把服務端程式碼放到雲伺服器上)

在阿里雲伺服器執行socket簡單的服務端程式碼

目錄


  • 昨天初學的socket測試程式碼是用127.0.0.1電腦本地迴環測試的,真的要驗證行不行,還得放到雲伺服器上。connect()失敗了半天,先是測試了客戶端是否有問題。用連線百度ip和8080埠的方法,發現是可以connect成功 的,所以轉而看服務端程式碼是否有問題。
  • 在雲伺服器上執行服務端程式碼,開啟另一個終端輸入命令lsof -i:埠號,檢視那個埠號的工作狀態,發現那個埠號其實也是正常處於監聽狀態的,程式碼似乎並沒有錯
  • 面向百度,折騰了半天,發現雲伺服器有些知識點還真得需要記錄下來。

貼上程式碼:

Client

void My_client(void){
    char buf[128] = {0};
    struct iovec buffer={
        .iov_base = buf,
        .iov_len = sizeof(buf)
    };
    struct msghdr Mymsg={
        .msg_name = nullptr,
        .msg_namelen = 0,
        .msg_iov = &buffer,
        .msg_iovlen = 1,
        .msg_control = nullptr,
        .msg_controllen = 0,
        .msg_flags = 0
    };

    int Mysocket = socket(AF_INET,SOCK_STREAM,0);

    struct sockaddr_in Server_Addr;
    
    bzero(&Server_Addr,sizeof(Server_Addr));//memset(&Server_Addr,0,sizeof(Server_Addr)); 
    
    Server_Addr.sin_family=AF_INET;
    Server_Addr.sin_addr.s_addr=inet_addr("填入伺服器的公網地址");  //強調是公網地址
    Server_Addr.sin_port=htons(12345);  //要訪問的埠,這個是服務端程式決定的
    
    cout << "connect...."<<endl;
    int res = connect(Mysocket,(struct sockaddr*)&Server_Addr,sizeof(Server_Addr));
    if(res!=-1){//對伺服器傳送連線請求
        cout<<"connect succ"<<endl;
        std::cout << "ready accept message"<<endl;
        recvmsg(Mysocket,&Mymsg,0); //接收資訊
        printf("%s\n",Mymsg.msg_iov->iov_base);
        std::cout << "read message done"<<endl;
    }else{
        std::cout<<"connect fail! res :" << res <<endl;
    }
    
    system("netstat -an | grep 12345");

    close(Mysocket);
}

Server

void My_server(void){
      //初始化傳送資料緩衝區
      char buf[128]={0};
      struct iovec buffer={
          .iov_base = buf,
          .iov_len = sizeof(buf)
      };
      struct msghdr Mymsg={
          .msg_name = nullptr,
          .msg_namelen =0,
          .msg_iov = &buffer,
          .msg_iovlen = 1,
          .msg_control = nullptr,
          .msg_controllen = 0,
          .msg_flags = 0
      };
      //建立套接字
      int Mysocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
      //將套接字和IP、埠繫結
      struct sockaddr_in Server_Addr;
      memset(&Server_Addr,0,sizeof(Server_Addr));
      Server_Addr.sin_family=AF_INET; //設定使用ipv4地址   
      Server_Addr.sin_addr.s_addr=inet_addr("雲伺服器私有地址");//強調私有地址,和公有地址不同的
      Server_Addr.sin_port=htons(12345); //設定監聽的埠
      bind(Mysocket,(struct sockaddr *)&Server_Addr,sizeof(Server_Addr));
 
      //進入監聽狀態
      listen(Mysocket,10);
      //接收客戶端請求
      struct sockaddr_in client_addr;
      socklen_t client_size = sizeof(client_addr);
      std::cout << "ready to accept!...."<<endl;
      int client_sock = accept(Mysocket,(struct sockaddr*)&client_addr,&client_size);//在此阻塞
      std::cout << "accept finish!.."<<endl;
      //向客戶端傳送資料
      char str[] = "hello,world!";
      Mymsg.msg_iov->iov_base = str;
 
      sendmsg(client_sock,&Mymsg,0); //write(client_sock,str,sizeof(str));用write也是可以的
      close(client_sock);
  • 程式碼的功能就是客戶端連線服務端成功之後,服務端傳送一個字串給客戶端,然後各自斷開連線,結束程式。

阿里雲伺服器配置
  • 前提是不考慮安全性,畢竟為了解決問題把防火牆關掉了...
  • 要注意的幾點:

1.阿里雲伺服器控制檯的安全組裡開啟埠
2.客戶端訪問的是雲伺服器的公有ip,服務端監聽的是雲伺服器的私有ip
3.關閉防火牆(實際我前兩步都做好了,但是還是連線不上,最後才百度到關閉防火牆,應該有更好的解決辦法吧)

  • 阿里雲伺服器關閉防火牆方法
  1. 首先要有firewall這個命令,沒有的話用apt install firewall獲取(伺服器系統是ubuntu)
  2. 然後輸入命令systemctl stop firewalld即可關閉防火牆