3、一個簡單的socket通信實例
阿新 • • 發佈:2018-09-06
創建 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通信實例