linux下socket通信程序例子

[代碼] c代碼 server部分

001 server.c
002   
003 ====================================================================
004   
005 #include <netinet/in.h>    // for sockaddr_in
006 #include <sys/types.h>    // for socket
007 #include <sys/socket.h>    // for socket
008 #include <stdio.h>        // for printf
009 #include <stdlib.h>        // for exit
010 #include <string.h>        // for bzero
011 /*
012 #include <sys/types.h>
013 #include <sys/stat.h>
014 #include <fcntl.h>
015 #include <unistd.h>
016 */
017 #define HELLO_WORLD_SERVER_PORT    6666 
018 #define LENGTH_OF_LISTEN_QUEUE 20
019 #define BUFFER_SIZE 1024
020 #define FILE_NAME_MAX_SIZE 512
021   
022 int main(int argc, char **argv)
023 {
024     //設置一個socket地址結構server_addr,代表服務器internet地址, 端口
025     struct sockaddr_in server_addr;
026     bzero(&server_addr,sizeof(server_addr)); //把一段內存區的內容全部設置爲0
027     server_addr.sin_family = AF_INET;
028     server_addr.sin_addr.s_addr = htons(INADDR_ANY);
029     server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
030   
031     //創建用於internet的流協議(TCP)socket,用server_socket代表服務器socket
032     int server_socket = socket(PF_INET,SOCK_STREAM,0);
033     if( server_socket < 0)
034     {
035         printf("Create Socket Failed!");
036         exit(1);
037     }
038
039    int opt =1;
040    setsockopt(server_socket,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
041 }
042       
043     //把socket和socket地址結構聯繫起來
044     if( bind(server_socket,(struct sockaddr*)&server_addr,sizeof(server_addr)))
045     {
046         printf("Server Bind Port : %d Failed!", HELLO_WORLD_SERVER_PORT); 
047         exit(1);
048     }
049   
050     //server_socket用於監聽
051     if ( listen(server_socket, LENGTH_OF_LISTEN_QUEUE) )
052     {
053         printf("Server Listen Failed!"); 
054         exit(1);
055     }
056     while (1) //服務器端要一直運行
057     {
058         //定義客戶端的socket地址結構client_addr
059         struct sockaddr_in client_addr;
060         socklen_t length = sizeof(client_addr);
061   
062         //接受一個到server_socket代表的socket的一個連接
063         //如果沒有連接請求,就等待到有連接請求--這是accept函數的特性
064         //accept函數返回一個新的socket,這個socket(new_server_socket)用於同連接到的客戶的通信
065         //new_server_socket代表了服務器和客戶端之間的一個通信通道
066         //accept函數把連接到的客戶端信息填寫到客戶端的socket地址結構client_addr中
067         int new_server_socket = accept(server_socket,(struct sockaddr*)&client_addr,&length);
068         if ( new_server_socket < 0)
069         {
070             printf("Server Accept Failed!\n");
071             break;
072         }
073           
074         char buffer[BUFFER_SIZE];
075         bzero(buffer, BUFFER_SIZE);
076         length = recv(new_server_socket,buffer,BUFFER_SIZE,0);
077         if (length < 0)
078         {
079             printf("Server Recieve Data Failed!\n");
080             break;
081         }
082         char file_name[FILE_NAME_MAX_SIZE+1];
083         bzero(file_name, FILE_NAME_MAX_SIZE+1);
084         strncpy(file_name, buffer, strlen(buffer)>FILE_NAME_MAX_SIZE?FILE_NAME_MAX_SIZE:strlen(buffer));
085 //        int fp = open(file_name, O_RDONLY);
086 //        if( fp < 0 )
087         printf("%s\n",file_name);
088         FILE * fp = fopen(file_name,"r");
089         if(NULL == fp )
090         {
091             printf("File:\t%s Not Found\n", file_name);
092         }
093         else
094         {
095             bzero(buffer, BUFFER_SIZE);
096             int file_block_length = 0;
097 //            while( (file_block_length = read(fp,buffer,BUFFER_SIZE))>0)
098             while( (file_block_length = fread(buffer,sizeof(char),BUFFER_SIZE,fp))>0)
099             {
100                 printf("file_block_length = %d\n",file_block_length);
101                 //發送buffer中的字符串到new_server_socket,實際是給客戶端
102                 if(send(new_server_socket,buffer,file_block_length,0)<0)
103                 {
104                     printf("Send File:\t%s Failed\n", file_name);
105                     break;
106                 }
107                 bzero(buffer, BUFFER_SIZE);
108             }
109 //            close(fp);
110             fclose(fp);
111             printf("File:\t%s Transfer Finished\n",file_name);
112         }
113         //關閉與客戶端的連接
114         close(new_server_socket);
115     }
116     //關閉監聽用的socket
117     close(server_socket);
118     return 0;
119 }

[代碼] c代碼 client部分

001 client.c
002   
003 #include <netinet/in.h>    // for sockaddr_in
004 #include <sys/types.h>    // for socket
005 #include <sys/socket.h>    // for socket
006 #include <stdio.h>        // for printf
007 #include <stdlib.h>        // for exit
008 #include <string.h>        // for bzero
009 /*
010 #include <sys/types.h>
011 #include <sys/stat.h>
012 #include <fcntl.h>
013 #include <unistd.h>
014 */
015   
016 #define HELLO_WORLD_SERVER_PORT    6666 
017 #define BUFFER_SIZE 1024
018 #define FILE_NAME_MAX_SIZE 512
019   
020 int main(int argc, char **argv)
021 {
022     if (argc != 2)
023     {
024         printf("Usage: ./%s ServerIPAddress\n",argv[0]);
025         exit(1);
026     }
027   
028     //設置一個socket地址結構client_addr,代表客戶機internet地址, 端口
029     struct sockaddr_in client_addr;
030     bzero(&client_addr,sizeof(client_addr)); //把一段內存區的內容全部設置爲0
031     client_addr.sin_family = AF_INET;    //internet協議族
032     client_addr.sin_addr.s_addr = htons(INADDR_ANY);//INADDR_ANY表示自動獲取本機地址
033     client_addr.sin_port = htons(0);    //0表示讓系統自動分配一個空閒端口
034     //創建用於internet的流協議(TCP)socket,用client_socket代表客戶機socket
035     int client_socket = socket(AF_INET,SOCK_STREAM,0);
036     if( client_socket < 0)
037     {
038         printf("Create Socket Failed!\n");
039         exit(1);
040     }
041     //把客戶機的socket和客戶機的socket地址結構聯繫起來
042     if( bind(client_socket,(struct sockaddr*)&client_addr,sizeof(client_addr)))
043     {
044         printf("Client Bind Port Failed!\n"); 
045         exit(1);
046     }
047   
048     //設置一個socket地址結構server_addr,代表服務器的internet地址, 端口
049     struct sockaddr_in server_addr;
050     bzero(&server_addr,sizeof(server_addr));
051     server_addr.sin_family = AF_INET;
052     if(inet_aton(argv[1],&server_addr.sin_addr) == 0) //服務器的IP地址來自程序的參數
053     {
054         printf("Server IP Address Error!\n");
055         exit(1);
056     }
057     server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
058     socklen_t server_addr_length = sizeof(server_addr);
059     //向服務器發起連接,連接成功後client_socket代表了客戶機和服務器的一個socket連接
060     if(connect(client_socket,(struct sockaddr*)&server_addr, server_addr_length) < 0)
061     {
062         printf("Can Not Connect To %s!\n",argv[1]);
063         exit(1);
064     }
065   
066     char file_name[FILE_NAME_MAX_SIZE+1];
067     bzero(file_name, FILE_NAME_MAX_SIZE+1);
068     printf("Please Input File Name On Server:\t");
069     scanf("%s", file_name);
070       
071     char buffer[BUFFER_SIZE];
072     bzero(buffer,BUFFER_SIZE);
073     strncpy(buffer, file_name, strlen(file_name)>BUFFER_SIZE?BUFFER_SIZE:strlen(file_name));
074     //向服務器發送buffer中的數據
075     send(client_socket,buffer,BUFFER_SIZE,0);
076   
077 //    int fp = open(file_name, O_WRONLY|O_CREAT);
078 //    if( fp < 0 )
079     FILE * fp = fopen(file_name,"w");
080     if(NULL == fp )
081     {
082         printf("File:\t%s Can Not Open To Write\n", file_name);
083         exit(1);
084     }
085       
086     //從服務器接收數據到buffer中
087     bzero(buffer,BUFFER_SIZE);
088     int length = 0;
089     while( length = recv(client_socket,buffer,BUFFER_SIZE,0))
090     {
091         if(length < 0)
092         {
093             printf("Recieve Data From Server %s Failed!\n", argv[1]);
094             break;
095         }
096 //        int write_length = write(fp, buffer,length);
097         int write_length = fwrite(buffer,sizeof(char),length,fp);
098         if (write_length<length)
099         {
100             printf("File:\t%s Write Failed\n", file_name);
101             break;
102         }
103         bzero(buffer,BUFFER_SIZE);    
104     }
105     printf("Recieve File:\t %s From Server[%s] Finished\n",file_name, argv[1]);
106       
107     close(fp);
108     //關閉socket
109     close(client_socket);
110     return 0;
111 }

[代碼] open等,fopen等說明

01 某些註釋部分,open,read,write被 fopen,fread,fwrite替換。
02   
03 說明一下:
04 fopen, fclose, fread, fwrite, fgetc, fgets, fputc, fputs, freopen, fseek, ftell, rewind
05 緩衝文件系統
06 緩衝文件系統的特點是:在內存開闢一個“緩衝區”,爲程序中的每一個文件使用,當執行讀文件的操作時,
07 從磁盤文件將數據先讀入內存“緩衝區”, 裝滿後再從內存“緩衝區”依此讀入接收的變量。執行寫文件的
08 操作時,先將數據寫入內存“緩衝區”,待內存“緩衝區”裝滿後再寫入文件。由此可以看出,內存 
09 “緩衝區”的大小,影響着實際操作外存的次數,內存“緩衝區”越大,則操作外存的次數就少,
10 執行速度就快、效率高。一般來說,文件“緩衝區”的大小隨機器 而定。
11   
12 open, close, read, write, getc, getchar, putc, putchar
13 非緩衝文件系統
14 非緩衝文件系統是藉助文件結構體指針來對文件進行管理,通過文件指針來對文件進行訪問,既可以讀寫字符、
15 字符串、格式化數據,也可以讀寫二進制數 據。非緩衝文件系統依賴於操作系統,通過操作系統的功能對
16 文件進行讀寫,是系統級的輸入輸出,它不設文件結構體指針,只能讀寫二進制文件,但效率高、速度快,
17 由於ANSI標準不再包括非緩衝文件系統,因此建議大家最好不要選擇它。
18   
19 open等屬於低級IO,
20 fopen等是高級IO。
21   
22 open等返回一個文件描述符(用戶程序區的),
23 fopen等返回一個文件指針。
24   
25 open等無緩衝,fopen等有緩衝。
26   
27 fopen等是在open等的基礎上擴充而來的,在大多數情況下,用fopen等。
28   
29 open 是系統調用 返回的是文件句柄,文件的句柄是文件在文件描述符表裏的索引,
30 fopen是C的庫函數,返回的是一個指向文件結構的指針。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章