1.tcp協議:傳輸控制協議---面向連線,傳輸可靠,面向位元組流。
實現資料可靠傳輸,傳輸靈活但是會造成資料粘包問題。
2.tcp客戶端與服務端通訊流程
3.**實現
//客戶端
1 #include"tcpsocket.hpp"
2 #include3
4 void sigcb(int signo)
5 8
9 int main(int argc, char* ar**)
10
16 std::string ip = ar**[1];
17 uint16_t port = atoi(ar**[2]);
18 19 signal(sigpipe, sigcb);
20 tcpsocket sock;
21 check_ret(sock.socket());
22 check_ret(sock.connect(ip, port));
23 while(1)
24
38 }
39 sock.close();
40 return 0;
41 }
//封裝好各個函式的標頭檔案
1 #include2 #include3 #include4 #include5 #include6 #include7 #include8 #include9 #include10 #define check_ret(q) if((q) == false)
11 12 class tcpsocket
13 16 ~tcpsocket(){}
17 bool socket()
18
25 return true;
26 }
27 28 bool bind(std::string& ip, uint16_t port)
29
42 return true;
43 }
44 45 bool listen(int backlog = 5)
46
53 return true;
54 }
55 56 bool accept(tcpsocket &cli, std::string &cliip, uint16_t port)
57
66 cli.setfd(sockfd);
67 cliip = inet_ntoa(addr.sin_addr);
68 port = ntohs(addr.sin_port);
69 return true;
70 }
71 72 void setfd(int sockfd)
73
76 77 bool connect(std::string& srv_ip, uint16_t srv_port)
78
91 return true;
92 }
93 94 bool send(std::string &buf)
95
102 return true;
103 }
104
105 bool recv(std::string &buf)
106
114 buf.assign(temp, ret);
115 return true;
116 }
117
118 bool close()
119
123 private:
124 int _socketfd;
125
126 };
4.**中的幾個函式:
htons():表示short型資料從主機位元組序轉到網路位元組序。
h:host(主機); n:net(網路); s:short(短整型)/ l:long(長整型)
同理還有ntohs() 、htonl() 、htonl()。
listen():宣告socket處於監聽狀態,其第二個引數為允許的客戶端最大併發連線數。
accept():從已完成連線佇列中獲取乙個客戶端新建的已完成連線的socket,如果沒有,則阻塞等待。
bind():客戶端沒有呼叫bind()函式,因為如果在同乙個機器上啟動多個客戶端,就會出現埠號被占用導致不能正確建立連線。
recv():返回0時,一定是tcp斷開連線,而不是傳輸資料大小為0,recv返回0,send觸發異常。
5.使用上面的**再啟動乙個客戶端,嘗試連線伺服器,會發現第二個客戶端不能正確與服務端通訊,這是因為我們accept了乙個請求之後,就一直在while迴圈嘗試讀取資料,沒有繼續呼叫accept導致不能接受新的請求。
所以使用多程序/多執行緒版本修改tcp的服務端程式即可。
//多程序版本服務端
#include #include #include "tcpsocket.hpp"
void sigcb(int no)
int main(int argc, char *ar**)
std::string ip = ar**[1];
uint16_t port = atoi(ar**[2]);
signal(sigchld, sigcb);
tcpsocket sock;
check_ret(sock.socket());
check_ret(sock.bind(ip, port));
check_ret(sock.listen());
while(1)
std::cout< buf;
clisock.send(buf);
}clisock.close();
exit(0);
}//父程序一定要關閉這個套接字;因為父子程序資料獨有
//父程序關閉對子程序無影響;不關閉會造成資源洩漏
clisock.close();
}sock.close();
}
//多執行緒版本服務端
#include #include "tcpsocket.hpp"
void *thr_start(void *arg)
clisock->close();
delete clisock;
return null;
}int main(int argc, char *ar**)
std::string ip = ar**[1];
uint16_t port = atoi(ar**[2]);
tcpsocket sock;
check_ret(sock.socket());
check_ret(sock.bind(ip, port));
check_ret(sock.listen());
while(1)
std::cout<
pthread_t tid;
pthread_create(&tid, null, thr_start, (void*)clisock);
pthread_detach(tid);
}sock.close();
}
TCP套接字程式設計
網路程式設計又稱為套接字程式設計,為了與遠端計算機進行資料傳輸,需要連線到網際網路,而程式設計中的 套接字 就是用來連線該網路的工具。它本身具有連線的含義,還可以表示為兩台計算機之間的網路連線。4.呼叫accept函式受理連線請求 基於tcp的服務端 客戶端 tcp伺服器端預設函式呼叫順序 sock...
TCP套接字程式設計
對於socket不理解的可以檢視 c語言通過socket程式設計實現tcp通訊,linux socket程式設計 socket詳解 先看看程式效果圖 提示如果伺服器,直接通過ctrl z關閉,這樣程式占用的位址不會釋放,需要以下操作 1.ps 檢視程序 2.kill 9 程式pid 強制殺死程序 服...
TCP套接字程式設計!!!
一 socket程式設計的基本函式詳解,其中根據客戶端還是服務端,或者根據使用tcp還是udp,函式的呼叫流程有些許區別 1 socket 函式用於建立乙個套接字,一條通訊線路的端點。3 listen 在服務端程式成功建立套接字和與位址進行繫結之後,還需要準備在該套接字上接收新的連線請求。此時呼叫l...