Linux下socket程式設計基礎1-初探(把服務端程式碼放到雲伺服器上)
阿新 • • 發佈:2020-09-16
在阿里雲伺服器執行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.關閉防火牆(實際我前兩步都做好了,但是還是連線不上,最後才百度到關閉防火牆,應該有更好的解決辦法吧)
- 阿里雲伺服器關閉防火牆方法
- 首先要有firewall這個命令,沒有的話用apt install firewall獲取(伺服器系統是ubuntu)
- 然後輸入命令systemctl stop firewalld即可關閉防火牆