建立套接字
intserv_sock
=socket
(af_inet
,sock_stream
,ipproto_tcp
);第乙個引數指定應用程式使用的通訊協議的協議族,對於tcp/ip協議族,該引數置
af_inet
;第二個引數指定要建立的套接字型別,流套接字型別為
sock_stream
、資料報套接字型別為
sock_dgram
、原始套接字
sock_raw
(winsock介面並不適用某種特定的協議去封裝它,而是由程式自行處理資料報以及協議首部);
第三個引數指定應用程式所使用的通訊協議。此引數可以指定單個協議系列中的不同傳輸協議。在internet通訊域中,此引數一般取值為0,系統會根據套接字的型別決定應使用的傳輸層協議。
socket返回值是乙個識別符號,後面的所有函式呼叫都使用這個識別符號來描述套接字。
struct
sockaddr_in serv_addr
;//就假設這個結構是套接字上面的目的位址,具體的我也不清楚啊
memset
(&serv_addr,0
,sizeof
(serv_addr
));//每個位元組都用0填充
serv_addr
.sin_family
=af_inet
;//使用ipv4位址,指定協議族
serv_addr
.sin_addr
.s_addr
=inet_addr
("127.0.0.1"
);serv_addr
.sin_port
=htons
(1234
);//埠:htons
是將整型變數從主機位元組順序轉變成網路位元組順序, 就是整數在位址空間儲存方式變為:高位位元組存放在記憶體的低位址處。
服務端服務端首先需要建立監聽套接字
bind
(serv_sock,(
struct
sockaddr
*)&serv_addr
,sizeof
(serv_addr
));//將套接字與目的位址繫結起來
listen
(serv_sock,20
);//
監聽套接字
客戶端注意客戶端並不會建立監聽套接字
connect
(sock,(
struct
sockaddr
*)&serv_addr
,sizeof
(serv_addr
));
然後服務端開啟,等待客戶端連線,然後建立乙個連線套接字
這兒可以用while(true)或者for(;;)來持續監聽來自客戶端的連線。
struct
sockaddr_in clnt_addr
;//客戶端傳過來的目的位址
socklen_t clnt_addr_size
=sizeof
(clnt_addr
);int
clnt_sock
=accept
(serv_sock,(
struct
sockaddr
*)&clnt_addr,&
clnt_addr_size);
如果客戶端有連線請求,必須使用下述函式來接受客戶端的請求。
socket accept(
socket s,
struct sockaddr far *addr,
int far *addrlen
);
addr用於存放客戶端的位址,addrlen在呼叫函式時被設定為addr指向區域的長度,在函式呼叫結束後被設定為實際位址資訊的長度。本函式會阻塞等待直到有客戶端請求到達。
返回值是乙個新的套接字描述符,它代表的是和客戶端的新的連線,這個套接字就是連線套接字,包含的是客戶端的ip和port資訊 ,而引數中的socket s包含的是伺服器的ip和port資訊 。(當然這個new_socket會從serv_sock中繼承 伺服器的ip和port資訊,兩種都有了,就組成了乙個套接字對,注意服務端與客戶端是通過套接字對聯絡的,tcp必須檢視套接字對的所有4個元素(客戶端/服務端的ip/port)才能確定由哪個端點接收某個達到的分組)。
系統呼叫 accept() 會有點古怪的地方的!你可以想象發生 這樣的事情:有人從很遠的地方通過乙個你在偵聽 (listen()) 的埠連線 (connect()) 到你的機器。它的連線將加入到等待接受 (accept()) 的佇列 中。你呼叫 accept() 告訴它你有空閒的連線。它將返回乙個新的套接字文 件描述符!這樣你就有兩個套接字了,原來的乙個還在偵聽你的那個埠, 新的在準備傳送 (send()) 和接收 ( recv()) 資料。這就是這個過程!
也就是說,在連線建立後,客戶端用發出連線的那個socket向伺服器發資料,是發給伺服器新建立的socket,而不是伺服器的監聽socket。伺服器的監聽socket永遠只是用來接受連線請求。
這就好比你去吃飯,飯館門口有迎賓小姐(監聽socket)看到你來後和你打招呼,然後(accept)找來乙個新的服務員(new socket)來接待你,然後守在門口繼續監聽下乙個。監聽的小姐走了,接待你的服務員當然不受影響。
建立連線套接字後就可以開始客戶端與服務端的聯絡
注意send/recv 及write/read的區別,這裡稍後再整理吧。
聯絡的話就可以幹很多事情了,balabala......
服務端
charstr
="hello world!"
;write
(clnt_sock
,str
,sizeof
(str
));//通過連線套接字對傳送訊息
客戶端char
buffer[40
];read
(sock
,buffer
,sizeof
(buffer)-1
);//通過連線套接字對接受訊息
printf
("message form server: %s\n"
,buffer
);//在客戶端顯示來自主機的訊息
最後通訊結束,關閉套接字對
close
(clnt_sock
);close
(serv_sock
);//注意服務端還需要關閉監聽套接字。
對於Stack的簡單理解
stack其實很簡單,感覺陌生的主要的原因是新手沒怎麼接觸過或者不常用,以及對stack本質上到底是什麼東西不清楚,如果知道了stack本質上到底是個什麼東西,stack就再簡單不過了。stack 本質上就是乙個 集合 跟 arraylist 集合一樣,都是儲存資料的乙個集合。因此,stack也就很...
對於ajax的簡單理解
jquery 中load 方法是簡單強大的ajax方法,這個方法是在從伺服器載入資料,並且返回資料放入選擇器選擇的元素中。它的語法結構是這樣的 selector load url,data,callback url是乙個必須引數,就是需要載入的url,date和callback是都是可選引數,dat...
對於epollout的簡單理解
今天聽大神說到了epoll 中的epollout 事件,我基本沒有用過這種東西,我並不知道這個有什麼用?epollout 主要是用來傳輸大量資料的時候,沒有辦法一次將資料全部傳送出去就需要將剩下的資料快取起來,等核心通知緩衝區可寫的時候再繼續傳送 epollout 在傳送大型檔案的時候需要進行處理,...