socket起源於Unix,而Unix/Linux基本哲學之一就是「一切皆文件」,均可以用「打開open –> 讀寫write/read –> 關閉close」模式來操做。其實socket就是該模式的一個實現,socket便是一種特殊的文件,一些socket函數就是對其進行的操做(讀/寫IO、打開、關閉)編程
socket的做用是用於網絡通信,網絡通信通常指的是不一樣主機之間的進程通信,好比我電腦上的qq和你電腦上的qq實現通信,都是進程之間發送數據.網絡
在本地用pid標識一個進程,在網絡中,tcp/ip協議的網絡層「ip地址」能夠惟一標識網絡中的主機,傳輸層的「協議+端口」能夠惟一標識主機中的應用程序(進程)。(ip地址,協議,端口)就能夠標識網絡的進程了,網絡中的進程通訊就能夠利用這個標誌與其它進程進行交互socket
socket服務端編程基本步驟:tcp
1,建立套接字, 利用socket函數ide
2,綁定套接字: bind函數
3,監聽套件字: listenspa
4,accept,接收客戶端的鏈接,3次握手就發生在這個階段, 這個函數返回一個新的套接字code
5,處理業務server
socket客戶端:blog
1,建立套接字: socket
2,鏈接服務端: connect
3,處理業務
----------------------------------------------------------------------------------------------------------------------------------
服務端源碼:
1 #include <stdio.h> 2 #include <sys/types.h> 3 #include <sys/socket.h> 4 #include <stdlib.h> 5 #include <string.h> 6 #include <arpa/inet.h> 7 #include <unistd.h> 8 9 int main(int argc, char *argv[]) 10 { 11 int sockfd = -1; 12 int bindres = -1; 13 int listenres = -1; 14 15 sockfd = socket( AF_INET, SOCK_STREAM, 0 ); 16 if ( -1 == sockfd ) { 17 perror( "sock created" ); 18 exit( -1 ); 19 } 20 21 struct sockaddr_in server; 22 memset( &server, 0, sizeof( struct sockaddr_in ) ); 23 server.sin_family = AF_INET; 24 server.sin_port = 6666; 25 server.sin_addr.s_addr = htonl( INADDR_ANY ); 26 27 bindres = bind( sockfd, (struct sockaddr*)&server, sizeof( server ) ); 28 if( -1 == bindres ) { 29 perror( "sock bind" ); 30 exit( -1 ); 31 } 32 33 listenres = listen( sockfd, SOMAXCONN ); 34 if( -1 == listenres ) { 35 perror( "sock listen" ); 36 exit( -1 ); 37 } 38 39 struct sockaddr_in peerServer; 40 int acceptfd = -1; 41 socklen_t len = sizeof( peerServer ); 42 acceptfd = accept( sockfd, (struct sockaddr*)&peerServer, &len ); 43 if ( -1 == acceptfd ) { 44 perror( "sock accept" ); 45 exit( -1 ); 46 } 47 48 char recvBuf[1024]; 49 while( 1 ) { 50 memset( recvBuf, 0, sizeof( recvBuf ) ); 51 int recvBytes = read( acceptfd, recvBuf, sizeof( recvBuf ) ); 52 fputs( recvBuf, stdout ); 53 write( acceptfd,recvBuf, recvBytes ); 54 } 55 56 close( sockfd ); 57 close( acceptfd ); 58 59 return 0; 60 }
客戶端源碼:
1 #include <stdio.h> 2 #include <sys/types.h> 3 #include <sys/socket.h> 4 #include <stdlib.h> 5 #include <string.h> 6 #include <arpa/inet.h> 7 #include <unistd.h> 8 9 int main(int argc, char *argv[]) 10 { 11 int sockfd = -1; 12 13 sockfd = socket( AF_INET, SOCK_STREAM, 0 ); 14 if ( -1 == sockfd ) { 15 perror( "sock created" ); 16 exit( -1 ); 17 } 18 19 struct sockaddr_in server; 20 memset( &server, 0, sizeof( struct sockaddr_in ) ); 21 server.sin_family = AF_INET; 22 server.sin_port = 6666; 23 server.sin_addr.s_addr = inet_addr( "127.0.0.1" ); 24 25 int res = -1; 26 res = connect( sockfd, (struct sockaddr*)&server, sizeof( server ) ); 27 if( -1 == res ){ 28 perror( "sock connect" ); 29 exit( -1 ); 30 } 31 32 char sendBuf[1024] = { 0 }; 33 char recvBuf[1024] = { 0 }; 34 while( fgets( sendBuf, sizeof( sendBuf ), stdin ) != NULL ) { 35 write( sockfd, sendBuf, sizeof( sendBuf ) ); 36 read( sockfd, recvBuf, sizeof( recvBuf ) ); 37 fputs( recvBuf, stdout ); 38 memset( sendBuf, 0, sizeof( sendBuf ) ); 39 memset( recvBuf, 0, sizeof( recvBuf ) ); 40 } 41 42 close( sockfd ); 43 44 return 0; 45 }
一、socket函數的參數:當protocol爲0時,會自動選擇type類型對應的默認協議
二、將sin_addr設置爲INADDR_ANY"的含義是什麼?
轉換過來就是0.0.0.0,泛指本機的意思,也就是表示本機的全部IP,由於有些機子不止一塊網卡,多網卡的狀況下,這個就表示全部網卡ip地址的意思。 好比一臺電腦有3塊網卡,分別鏈接三個網絡,那麼這臺電腦就有3個ip地址了,若是某個應用程序須要監聽某個端口,那他要監聽哪一個網卡地址的端口呢? 若是綁定某個具體的ip地址,你只能監聽你所設置的ip地址所在的網卡的端口,其它兩塊網卡沒法監聽端口,若是我須要三個網卡都監聽,那就須要綁定3個ip,也就等於須要管理3個套接字進行數據交換,這樣豈不是很繁瑣? 因此出現INADDR_ANY,你只需綁定INADDR_ANY,管理一個套接字就行,無論數據是從哪一個網卡過來的,只要是綁定的端口號過來的數據,均可以接收到