宣告:此文只是為自己方便理解,做了一些具象的比喻和假設,並不符合客觀事實,謹慎閱讀!
在一台主機中, 兩個程序想要通訊可以通過乙個管道(檔案):乙個從管道的一端寫,乙個從另一端讀 , 然而管道是半雙工的 , 如果乙個程序既想讀又想寫 , 那就建立兩個管道。利用socket進行網路通訊的過程與之類似:將對方主機抽象成乙個全雙工管道檔案,為其建立檔案描述符,對這個檔案描述符進行讀寫。
int listen_fd = socket(af_inet, sock_stream, 0);
建立監聽套接字的目的是監聽是否有客戶端連線該主機,但只有乙個檔案描述符客戶端是找不到的,客戶端是通過ip位址和埠找到需要通訊的程序的,所以要將該listen_fd
與ip位址和埠繫結,方便起見,將ip與埠定義成乙個結構體。
// 先初始化ip + 埠 這個結構體
struct sockaddr_in server_addr;
server_addr.sin_family = af_inet;
// 設定埠
server_addr.sin_port = htons(8080);
// 設定ip
inet_pton(af_inet, "192.xx.***.xx", &server_addr.sin_addr.s_addr);
// 將監聽套接字與 ip+埠繫結
bind(listen_fd, (struct sockaddr*)&server_addr, sizeof(addr));
現在網路上已經有乙個「管道」通向伺服器,其他主機想要通訊並不是直接寫這個「管道」,而是通過該「管道」再申請乙個專門通訊的「管道」。原因很簡單,乙個服務大眾的人民公園不可能只設乙個大門。於是,主機通過listen_fd
監聽到有人來通訊,就新建立乙個「管道」來通訊。就好像住酒店,要先在前台(listen_fd)訂房間(client_fd),然後房間(client_fd)裡睡覺,而不能在前台(listen_fd)睡覺。
listen(listen_fd);
// 此時有使用者連線
struct sockaddr_in client_addr;
int client_fd = accept(listen_fd, (struct sockaddr*)&client_addr, &len);
此時就可以對client_fd
進行讀寫;
char buf[1024];
read(client_fd,buf,sizeof(buf));
write(client_fd, buf, sizeof(buf));
close(client_fd);
Socket網路通訊
服務端的程式如下 1.建立乙個伺服器端socket,即serversocket,指定繫結的埠,並監聽此埠8888 serversocket serversocket new serversocket 8888 socket socket null 記錄客戶端的數量 int count 0 syste...
socket網路通訊
read write recv send readv writev recvmsg sendmsg recvfrom sendto include ssize t read int fd,void buf,size t count ssize t write int fd,const void bu...
socket網路通訊《二》
socket網路通訊 本文注意基於socket來分析tcp連線建立過程。先回顧一下tcp連線建立過程 主機a執行的是tcp客戶端程式,主機b執行的是tcp伺服器程式,最初兩端tcp程序處於closed態,a主動開啟連線,對應客戶端connect函式發起連線,b被動接受連線,對應於伺服器listen函...