tcp套接字程式設計

2021-09-25 13:47:45 字數 4094 閱讀 9381

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...