日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux下使用socket传输文件的C语言简单实现

發布時間:2023/11/30 linux 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux下使用socket传输文件的C语言简单实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉載:http://blog.csdn.net/ljd_1986413/article/details/7940938

服務器程序和客戶端程序應當分別運行在兩臺計算機上。

在運行服務器端的計算機終端執行:./file_server

在運行客戶端的計算終端上執行:./file_client?? ipaddr_server

然后根據提示輸入要傳輸的服務器上的文件,該文件必須在服務器的當前運行目錄中,否則會提示找不到文件。

?

直接上源碼吧:

?

[cpp]?view plaincopy
  • ??
  • //?file_server.c?--?socket文件傳輸服務器端示例代碼???
  • //?/??
  • #include<netinet/in.h>???
  • #include<sys/types.h>???
  • #include<sys/socket.h>???
  • #include<stdio.h>???
  • #include<stdlib.h>???
  • #include<string.h>???
  • ??
  • #define?HELLO_WORLD_SERVER_PORT????6666??
  • #define?LENGTH_OF_LISTEN_QUEUE?????20??
  • #define?BUFFER_SIZE????????????????1024??
  • #define?FILE_NAME_MAX_SIZE?????????512??
  • ??
  • int?main(int?argc,?char?**argv)??
  • {??
  • ????//?set?socket's?address?information???
  • ????//?設置一個socket地址結構server_addr,代表服務器internet的地址和端口??
  • ????struct?sockaddr_in???server_addr;??
  • ????bzero(&server_addr,?sizeof(server_addr));??
  • ????server_addr.sin_family?=?AF_INET;??
  • ????server_addr.sin_addr.s_addr?=?htons(INADDR_ANY);??
  • ????server_addr.sin_port?=?htons(HELLO_WORLD_SERVER_PORT);??
  • ??
  • ????//?create?a?stream?socket???
  • ????//?創建用于internet的流協議(TCP)socket,用server_socket代表服務器向客戶端提供服務的接口??
  • ????int?server_socket?=?socket(PF_INET,?SOCK_STREAM,?0);??
  • ????if?(server_socket?<?0)??
  • ????{??
  • ????????printf("Create?Socket?Failed!\n");??
  • ????????exit(1);??
  • ????}??
  • ??
  • ????//?把socket和socket地址結構綁定???
  • ????if?(bind(server_socket,?(struct?sockaddr*)&server_addr,?sizeof(server_addr)))??
  • ????{??
  • ????????printf("Server?Bind?Port:?%d?Failed!\n",?HELLO_WORLD_SERVER_PORT);??
  • ????????exit(1);??
  • ????}??
  • ??
  • ????//?server_socket用于監聽???
  • ????if?(listen(server_socket,?LENGTH_OF_LISTEN_QUEUE))??
  • ????{??
  • ????????printf("Server?Listen?Failed!\n");??
  • ????????exit(1);??
  • ????}??
  • ??
  • ????//?服務器端一直運行用以持續為客戶端提供服務???
  • ????while(1)??
  • ????{??
  • ????????//?定義客戶端的socket地址結構client_addr,當收到來自客戶端的請求后,調用accept??
  • ????????//?接受此請求,同時將client端的地址和端口等信息寫入client_addr中??
  • ????????struct?sockaddr_in?client_addr;??
  • ????????socklen_t??????????length?=?sizeof(client_addr);??
  • ??
  • ????????//?接受一個從client端到達server端的連接請求,將客戶端的信息保存在client_addr中??
  • ????????//?如果沒有連接請求,則一直等待直到有連接請求為止,這是accept函數的特性,可以??
  • ????????//?用select()來實現超時檢測???
  • ????????//?accpet返回一個新的socket,這個socket用來與此次連接到server的client進行通信??
  • ????????//?這里的new_server_socket代表了這個通信通道??
  • ????????int?new_server_socket?=?accept(server_socket,?(struct?sockaddr*)&client_addr,?&length);??
  • ????????if?(new_server_socket?<?0)??
  • ????????{??
  • ????????????printf("Server?Accept?Failed!\n");??
  • ????????????break;??
  • ????????}??
  • ??
  • ????????char?buffer[BUFFER_SIZE];??
  • ????????bzero(buffer,?sizeof(buffer));??
  • ????????length?=?recv(new_server_socket,?buffer,?BUFFER_SIZE,?0);??
  • ????????if?(length?<?0)??
  • ????????{??
  • ????????????printf("Server?Recieve?Data?Failed!\n");??
  • ????????????break;??
  • ????????}??
  • ??
  • ????????char?file_name[FILE_NAME_MAX_SIZE?+?1];??
  • ????????bzero(file_name,?sizeof(file_name));??
  • ????????strncpy(file_name,?buffer,??
  • ????????????????strlen(buffer)?>?FILE_NAME_MAX_SIZE???FILE_NAME_MAX_SIZE?:?strlen(buffer));??
  • ??
  • ????????FILE?*fp?=?fopen(file_name,?"r");??
  • ????????if?(fp?==?NULL)??
  • ????????{??
  • ????????????printf("File:\t%s?Not?Found!\n",?file_name);??
  • ????????}??
  • ????????else??
  • ????????{??
  • ????????????bzero(buffer,?BUFFER_SIZE);??
  • ????????????int?file_block_length?=?0;??
  • ????????????while(?(file_block_length?=?fread(buffer,?sizeof(char),?BUFFER_SIZE,?fp))?>?0)??
  • ????????????{??
  • ????????????????printf("file_block_length?=?%d\n",?file_block_length);??
  • ??
  • ????????????????//?發送buffer中的字符串到new_server_socket,實際上就是發送給客戶端??
  • ????????????????if?(send(new_server_socket,?buffer,?file_block_length,?0)?<?0)??
  • ????????????????{??
  • ????????????????????printf("Send?File:\t%s?Failed!\n",?file_name);??
  • ????????????????????break;??
  • ????????????????}??
  • ??
  • ????????????????bzero(buffer,?sizeof(buffer));??
  • ????????????}??
  • ????????????fclose(fp);??
  • ????????????printf("File:\t%s?Transfer?Finished!\n",?file_name);??
  • ????????}??
  • ??
  • ????????close(new_server_socket);??
  • ????}??
  • ??
  • ????close(server_socket);??
  • ??
  • ????return?0;??
  • }??
  • [cpp]?view plain?copy
  • ??
  • //?file_server.c?--?socket文件傳輸服務器端示例代碼??
  • //?/??
  • #include<netinet/in.h>??
  • #include<sys/types.h>??
  • #include<sys/socket.h>??
  • #include<stdio.h>??
  • #include<stdlib.h>??
  • #include<string.h>??
  • ??
  • #define?HELLO_WORLD_SERVER_PORT????6666??
  • #define?LENGTH_OF_LISTEN_QUEUE?????20??
  • #define?BUFFER_SIZE????????????????1024??
  • #define?FILE_NAME_MAX_SIZE?????????512??
  • ??
  • int?main(int?argc,?char?**argv)??
  • {??
  • ????//?set?socket's?address?information??
  • ????//?設置一個socket地址結構server_addr,代表服務器internet的地址和端口??
  • ????struct?sockaddr_in???server_addr;??
  • ????bzero(&server_addr,?sizeof(server_addr));??
  • ????server_addr.sin_family?=?AF_INET;??
  • ????server_addr.sin_addr.s_addr?=?htons(INADDR_ANY);??
  • ????server_addr.sin_port?=?htons(HELLO_WORLD_SERVER_PORT);??
  • ??
  • ????//?create?a?stream?socket??
  • ????//?創建用于internet的流協議(TCP)socket,用server_socket代表服務器向客戶端提供服務的接口??
  • ????int?server_socket?=?socket(PF_INET,?SOCK_STREAM,?0);??
  • ????if?(server_socket?<?0)??
  • ????{??
  • ????????printf("Create?Socket?Failed!\n");??
  • ????????exit(1);??
  • ????}??
  • ??
  • ????//?把socket和socket地址結構綁定??
  • ????if?(bind(server_socket,?(struct?sockaddr*)&server_addr,?sizeof(server_addr)))??
  • ????{??
  • ????????printf("Server?Bind?Port:?%d?Failed!\n",?HELLO_WORLD_SERVER_PORT);??
  • ????????exit(1);??
  • ????}??
  • ??
  • ????//?server_socket用于監聽??
  • ????if?(listen(server_socket,?LENGTH_OF_LISTEN_QUEUE))??
  • ????{??
  • ????????printf("Server?Listen?Failed!\n");??
  • ????????exit(1);??
  • ????}??
  • ??
  • ????//?服務器端一直運行用以持續為客戶端提供服務??
  • ????while(1)??
  • ????{??
  • ????????//?定義客戶端的socket地址結構client_addr,當收到來自客戶端的請求后,調用accept??
  • ????????//?接受此請求,同時將client端的地址和端口等信息寫入client_addr中??
  • ????????struct?sockaddr_in?client_addr;??
  • ????????socklen_t??????????length?=?sizeof(client_addr);??
  • ??
  • ????????//?接受一個從client端到達server端的連接請求,將客戶端的信息保存在client_addr中??
  • ????????//?如果沒有連接請求,則一直等待直到有連接請求為止,這是accept函數的特性,可以??
  • ????????//?用select()來實現超時檢測??
  • ????????//?accpet返回一個新的socket,這個socket用來與此次連接到server的client進行通信??
  • ????????//?這里的new_server_socket代表了這個通信通道??
  • ????????int?new_server_socket?=?accept(server_socket,?(struct?sockaddr*)&client_addr,?&length);??
  • ????????if?(new_server_socket?<?0)??
  • ????????{??
  • ????????????printf("Server?Accept?Failed!\n");??
  • ????????????break;??
  • ????????}??
  • ??
  • ????????char?buffer[BUFFER_SIZE];??
  • ????????bzero(buffer,?sizeof(buffer));??
  • ????????length?=?recv(new_server_socket,?buffer,?BUFFER_SIZE,?0);??
  • ????????if?(length?<?0)??
  • ????????{??
  • ????????????printf("Server?Recieve?Data?Failed!\n");??
  • ????????????break;??
  • ????????}??
  • ??
  • ????????char?file_name[FILE_NAME_MAX_SIZE?+?1];??
  • ????????bzero(file_name,?sizeof(file_name));??
  • ????????strncpy(file_name,?buffer,??
  • ????????????????strlen(buffer)?>?FILE_NAME_MAX_SIZE???FILE_NAME_MAX_SIZE?:?strlen(buffer));??
  • ??
  • ????????FILE?*fp?=?fopen(file_name,?"r");??
  • ????????if?(fp?==?NULL)??
  • ????????{??
  • ????????????printf("File:\t%s?Not?Found!\n",?file_name);??
  • ????????}??
  • ????????else??
  • ????????{??
  • ????????????bzero(buffer,?BUFFER_SIZE);??
  • ????????????int?file_block_length?=?0;??
  • ????????????while(?(file_block_length?=?fread(buffer,?sizeof(char),?BUFFER_SIZE,?fp))?>?0)??
  • ????????????{??
  • ????????????????printf("file_block_length?=?%d\n",?file_block_length);??
  • ??
  • ????????????????//?發送buffer中的字符串到new_server_socket,實際上就是發送給客戶端??
  • ????????????????if?(send(new_server_socket,?buffer,?file_block_length,?0)?<?0)??
  • ????????????????{??
  • ????????????????????printf("Send?File:\t%s?Failed!\n",?file_name);??
  • ????????????????????break;??
  • ????????????????}??
  • ??
  • ????????????????bzero(buffer,?sizeof(buffer));??
  • ????????????}??
  • ????????????fclose(fp);??
  • ????????????printf("File:\t%s?Transfer?Finished!\n",?file_name);??
  • ????????}??
  • ??
  • ????????close(new_server_socket);??
  • ????}??
  • ??
  • ????close(server_socket);??
  • ??
  • ????return?0;??
  • }??

  • ?

    [cpp]?view plaincopyprint?
  • //??
  • //?file_client.c??socket傳輸文件的client端示例程序???
  • //?///??
  • #include<netinet/in.h>?????????????????????????//?for?sockaddr_in??
  • #include<sys/types.h>??????????????????????????//?for?socket??
  • #include<sys/socket.h>?????????????????????????//?for?socket??
  • #include<stdio.h>??????????????????????????????//?for?printf??
  • #include<stdlib.h>?????????????????????????????//?for?exit??
  • #include<string.h>?????????????????????????????//?for?bzero??
  • ??
  • #define?HELLO_WORLD_SERVER_PORT???????6666??
  • #define?BUFFER_SIZE???????????????????1024??
  • #define?FILE_NAME_MAX_SIZE????????????512??
  • ??
  • int?main(int?argc,?char?**argv)??
  • {??
  • ????if?(argc?!=?2)??
  • ????{??
  • ????????printf("Usage:?./%s?ServerIPAddress\n",?argv[0]);??
  • ????????exit(1);??
  • ????}??
  • ??
  • ????//?設置一個socket地址結構client_addr,?代表客戶機的internet地址和端口??
  • ????struct?sockaddr_in?client_addr;??
  • ????bzero(&client_addr,?sizeof(client_addr));??
  • ????client_addr.sin_family?=?AF_INET;?//?internet協議族??
  • ????client_addr.sin_addr.s_addr?=?htons(INADDR_ANY);?//?INADDR_ANY表示自動獲取本機地址??
  • ????client_addr.sin_port?=?htons(0);?//?auto?allocated,?讓系統自動分配一個空閑端口??
  • ??
  • ????//?創建用于internet的流協議(TCP)類型socket,用client_socket代表客戶端socket??
  • ????int?client_socket?=?socket(AF_INET,?SOCK_STREAM,?0);??
  • ????if?(client_socket?<?0)??
  • ????{??
  • ????????printf("Create?Socket?Failed!\n");??
  • ????????exit(1);??
  • ????}??
  • ??
  • ????//?把客戶端的socket和客戶端的socket地址結構綁定???
  • ????if?(bind(client_socket,?(struct?sockaddr*)&client_addr,?sizeof(client_addr)))??
  • ????{??
  • ????????printf("Client?Bind?Port?Failed!\n");??
  • ????????exit(1);??
  • ????}??
  • ??
  • ????//?設置一個socket地址結構server_addr,代表服務器的internet地址和端口??
  • ????struct?sockaddr_in??server_addr;??
  • ????bzero(&server_addr,?sizeof(server_addr));??
  • ????server_addr.sin_family?=?AF_INET;??
  • ??
  • ????//?服務器的IP地址來自程序的參數???
  • ????if?(inet_aton(argv[1],?&server_addr.sin_addr)?==?0)??
  • ????{??
  • ????????printf("Server?IP?Address?Error!\n");??
  • ????????exit(1);??
  • ????}??
  • ??
  • ????server_addr.sin_port?=?htons(HELLO_WORLD_SERVER_PORT);??
  • ????socklen_t?server_addr_length?=?sizeof(server_addr);??
  • ??
  • ????//?向服務器發起連接請求,連接成功后client_socket代表客戶端和服務器端的一個socket連接??
  • ????if?(connect(client_socket,?(struct?sockaddr*)&server_addr,?server_addr_length)?<?0)??
  • ????{??
  • ????????printf("Can?Not?Connect?To?%s!\n",?argv[1]);??
  • ????????exit(1);??
  • ????}??
  • ??
  • ????char?file_name[FILE_NAME_MAX_SIZE?+?1];??
  • ????bzero(file_name,?sizeof(file_name));??
  • ????printf("Please?Input?File?Name?On?Server.\t");??
  • ????scanf("%s",?file_name);??
  • ??
  • ????char?buffer[BUFFER_SIZE];??
  • ????bzero(buffer,?sizeof(buffer));??
  • ????strncpy(buffer,?file_name,?strlen(file_name)?>?BUFFER_SIZE???BUFFER_SIZE?:?strlen(file_name));??
  • ????//?向服務器發送buffer中的數據,此時buffer中存放的是客戶端需要接收的文件的名字??
  • ????send(client_socket,?buffer,?BUFFER_SIZE,?0);??
  • ??
  • ????FILE?*fp?=?fopen(file_name,?"w");??
  • ????if?(fp?==?NULL)??
  • ????{??
  • ????????printf("File:\t%s?Can?Not?Open?To?Write!\n",?file_name);??
  • ????????exit(1);??
  • ????}??
  • ??
  • ????//?從服務器端接收數據到buffer中???
  • ????bzero(buffer,?sizeof(buffer));??
  • ????int?length?=?0;??
  • ????while(length?=?recv(client_socket,?buffer,?BUFFER_SIZE,?0))??
  • ????{??
  • ????????if?(length?<?0)??
  • ????????{??
  • ????????????printf("Recieve?Data?From?Server?%s?Failed!\n",?argv[1]);??
  • ????????????break;??
  • ????????}??
  • ??
  • ????????int?write_length?=?fwrite(buffer,?sizeof(char),?length,?fp);??
  • ????????if?(write_length?<?length)??
  • ????????{??
  • ????????????printf("File:\t%s?Write?Failed!\n",?file_name);??
  • ????????????break;??
  • ????????}??
  • ????????bzero(buffer,?BUFFER_SIZE);??
  • ????}??
  • ??
  • ????printf("Recieve?File:\t?%s?From?Server[%s]?Finished!\n",?file_name,?argv[1]);??
  • ??
  • ????//?傳輸完畢,關閉socket???
  • ????fclose(fp);??
  • ????close(client_socket);??
  • ????return?0;??
  • ??
  • }??
  • 客戶端不一定要bind(),服務端一定要bind(),為什么?不然客戶端怎么知道服務器位置(IP+PORT)。 一般客戶端不綁定端口,因為客戶程序經常開關, 由于一些原因(這里我說不清楚,你碰到了自然理解), 斷開時端口很少立刻釋放(一般要1、2分鐘)。 所以客戶端綁定端口容易出問題。?
    注:服務器綁定的是偵聽端口,客戶連接后,? 新分配一個sock和它連接(這個sock的port是不同的,相當于沒有bind的一個端口)? 由于偵聽端口是沒有實際聯接的,所以斷開時不需握手,也就沒有釋放問題了。???(注這段是回答時突然想到的,自我感覺是正確的,大家來批判啊)


    創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

    總結

    以上是生活随笔為你收集整理的Linux下使用socket传输文件的C语言简单实现的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。