linux socket編程:簡易客戶端與服務端


什么是socket?

socket起源於Unix,而Unix/Linux基本哲學之一就是“一切皆文件”,都可以用“打開open –> 讀寫write/read –> 關閉close”模式來操作。其實socket就是該模式的一個實現,socket即是一種特殊的文件,一些socket函數就是對其進行的操作(讀/寫IO、打開、關閉)

socket的作用是用於網絡通訊,網絡通訊一般指的是不同主機之間的進程通訊,比如我電腦上的qq和你電腦上的qq實現通訊,都是進程之間發送數據.

在本地用pid標識一個進程,在網絡中,tcp/ip協議的網絡層“ip地址”可以唯一標識網絡中的主機,傳輸層的“協議+端口”可以唯一標識主機中的應用程序(進程)。(ip地址,協議,端口)就可以標識網絡的進程了,網絡中的進程通信就可以利用這個標志與其它進程進行交互

socket服務端編程基本步驟:

1,創建套接字, 利用socket函數

2,綁定套接字: bind

3,監聽套件字: listen

4,accept,接收客戶端的連接,3次握手就發生在這個階段,  這個函數返回一個新的套接字

5,處理業務

socket客戶端:

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 }
View Code

客戶端源碼:

 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 }
View Code

備注:

1、socket函數的參數:當protocol為0時,會自動選擇type類型對應的默認協議

2、將sin_addr設置為INADDR_ANY"的含義是什么?

轉換過來就是0.0.0.0,泛指本機的意思,也就是表示本機的所有IP,因為有些機子不止一塊網卡,多網卡的情況下,這個就表示所有網卡ip地址的意思。 比如一台電腦有3塊網卡,分別連接三個網絡,那么這台電腦就有3個ip地址了,如果某個應用程序需要監聽某個端口,那他要監聽哪個網卡地址的端口呢? 如果綁定某個具體的ip地址,你只能監聽你所設置的ip地址所在的網卡的端口,其它兩塊網卡無法監聽端口,如果我需要三個網卡都監聽,那就需要綁定3個ip,也就等於需要管理3個套接字進行數據交換,這樣豈不是很繁瑣? 所以出現INADDR_ANY,你只需綁定INADDR_ANY,管理一個套接字就行,不管數據是從哪個網卡過來的,只要是綁定的端口號過來的數據,都可以接收到

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM