1. 程式人生 > >3、一個簡單的socket通信實例

3、一個簡單的socket通信實例

創建 ket 文件 it! png nbsp tin fflush exit

在Linux上實現的一個簡單的socket通信實例:

server.c

 1 #include<stdio.h>
 2 //下面兩個頭文件是使用socket必須引入的
 3 #include<sys/types.h>
 4 #include<sys/socket.h>
 5 
 6 #include<stdlib.h>
 7 #include<netinet/in.h>
 8 #include<arpa/inet.h>
 9  //啟動服務器通信端口
10 int startup(int _port,const char* _ip)
11
{ 12 //socket()函數打開一個網絡通信窗口,成功則返回一個文件描述符,應用程序可以向讀寫文件一樣用read/write在網絡上轉發數據。若調用出錯則返回-1 13 //socket()函數的三個參數:協議類型, 套接字類型, 協議類型的常量或設置為0 14 //AF_INET(IPv4協議) SOCK_STREAM字節流套接字 15 int sock=socket(AF_INET,SOCK_STREAM,0); 16 if(sock<0) 17 { 18 perror("socket"); 19 exit(1);
20 } 21 22 struct sockaddr_in local;//網絡編程中常用的數據結構 23 local.sin_family=AF_INET;//IPVC4地址族 24 local.sin_port=htons(_port);//將端口地址轉換為網絡二進制數字 25 local.sin_addr.s_addr=inet_addr(_ip);//將網絡地址轉換為網絡二進制數字 26 27 socklen_t len=sizeof(local); 28 //綁定套接字:成功返回0, 失敗返回-1 29 //功能:將sock和local綁定在一起,使得sock這個用於網絡通訊的問價描述符監聽local所描述的地址和端口
30 if(bind(sock,(struct sockaddr*)&local,len)<0) 31 { 32 perror("bind"); 33 exit(2); 34 } 35 //listen(int sockfd, int backlog)監聽函數,sockfd為要監聽的socket套接字,backlog為可以排隊的最大連接數。socket()函數創建的socket默認是一個主動類型的,listen函數將socket變為被動類型的,等待客戶的連接請求。監聽成功返回0, 失敗返回-1 36 if(listen(sock,5)<0) 37 { 38 perror("listen"); 39 exit(3); 40 } 41 return sock; 42 } 43 int main(int argc,char* argv[]) 44 { 45 if(argc!=3) 46 { 47 printf("Usage: [local_ip] [local_port]",argv[0]); 48 return 3; 49 } 50 //啟動服務器套接字listen_socket 51 int listen_socket=startup(atoi(argv[2]),argv[1]); 52 53 struct sockaddr_in remote; 54 socklen_t len=sizeof(struct sockaddr_in); 55 56 while(1) 57 { 58 //accept(int sockfd, struct sockaddr* addr, socklen_t* addrlen)函數,sockfd為服務器的socket套接字,addr為客戶端協議地址,addrlen為協議地址的長度, 59 //如果accept成功,則返回一個由內核自動生成的全新套接字,代表與返回客戶的TCP連接 60 int socket=accept(listen_socket,(struct sockaddr*)&remote,&len); 61 if(socket<0) 62 { 63 perror("accept"); 64 continue; 65 } 66 //inet_ntoa:將網絡二進制數字轉換為網絡地址 67 //ntohs:將網絡二進制數字轉換為端口號 68 printf("client,ip:%s,port:%d\n",inet_ntoa(remote.sin_addr)69 ,ntohs(remote.sin_port)); 70 71 72 char buf[1024]; 73 while(1) 74 { 75 //調用網絡I/O進行讀寫 76 ssize_t _s=read(socket,buf,sizeof(buf)-1); 77 if(_s>0) 78 { 79 buf[_s]=0; 80 printf("client# %s\n",buf); 81 } 82 else 83 { 84 printf("client is quit!\n"); 85 break; 86 } 87 88 } 89 //關閉套接字 90 close(socket); 91 } 92 return 0; 93 }

client.c

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<sys/types.h>
 4 #include<sys/socket.h>
 5 #include <netinet/in.h>
 6 #include <arpa/inet.h>
 7  
 8  
 9 static void usage(const char* proc)
10 {
11     printf("usage:%s [ip] [port]\n",proc);
12 }
13  
14 int main(int argc,char* argv[])
15 {
16    if(argc!=3)
17     {
18         usage(argv[0]);
19         return 3;
20     }
21     
22     int sock=socket(AF_INET,SOCK_STREAM,0);
23     if(sock<0)
24     {
25         perror("socket");
26         exit(1);
27     }
28  
29     struct sockaddr_in server;
30     server.sin_family=AF_INET;
31     server.sin_port=htons(atoi(argv[2]));
32     server.sin_addr.s_addr = inet_addr(argv[1]);
33     //connect(int sockfd, const struct sockaddr* addr, socklen_t addrlen);sockfd為要監聽的socket套接字,addr參數為服務器的socket地址,addrlen為socket地址的長度。客戶端通過調用connect函數來建立與TCP服務器的連接。
34     if(connect(sock,(struct sockaddr*)&server,(socklen_t)sizeof(server))<0)
35     {
36         perror("connect");
37         exit(2);
38     }
39  
40     char buf[1024];
41  
42     while(1)
43     {
44         printf("send#");
45         fflush(stdout);
46         ssize_t _s=read(0,buf,sizeof(buf)-1);
47         buf[_s-1]=0;
48         write(sock,buf,_s);
49     }
50     
51     close(sock);
52     return 0;
53  
54 }

結果展示:

技術分享圖片

技術分享圖片

3、一個簡單的socket通信實例