linux socket 編程(C語言)

https://www.cnblogs.com/x_wukong/p/4541010.html

最近看了一些網絡編程的書籍,一直以來總感覺網絡編程神秘莫測,其實網絡編程入門還是很容易學的,下面這些代碼是我在linux下編寫的,已經運行過了,編譯之后就可以運行了。有不足之處希望大家多多指出,共同學習交流。

???? 套接字是一種進程間的通信的方法,不同于以往介紹的進程間通信方法的是,它并不局限于同一臺計算機的資源,例如文件系統空間,共享內存或者消息隊列。套接字可以認為是對管道概念的擴展——一臺機器上的進程可以使用套接字與另一臺機器上的進程通信。因此客戶與服務器可以分散在網絡中。同一臺機器上的進程間也可以用套接字通信。套接字是一種通信機制,客戶/服務器系統既可以在本地單機上運行,也可以在網絡中運行。套接字與管道的區別:它明確區分客戶與服務器,可以實現將多個客戶連接到一個服務器。

?????套接字的工作過程(服務器端):首先,服務器應用程序通過socket系統調用創建一個套接字,它是系統分配給該服務器進程的類似文件描述符的資源,不能與其他進程共享。其次,服務器進程使用bind系統調用給套接字命名。本地套接字的名字是linux文件系統的文件名,一般放在/tmp或者/usr/tmp 目錄下。網絡套接字的名字是與客戶相連接的特定網絡有關的服務標識符。此標識符允許linux將進入的針對特定端口號的連接轉到正確的服務器進程。接下來,服務器進程開始等待客戶連接到這個命名套接字,調用listen創建一個等待隊列以便存放來自客戶的進入連接。最后,服務器通過accept系統調用來接受客戶的連接。此時,會產生一個與原有的命名套接字不同的新套接字,它僅用于與這個特定的客戶通信,而命名套接字則被保留下來繼續處理來自其他客戶的連接。??

?????套接字的工作過程(客戶端):調用socket創建一個未命名套接字,將服務器的命名套接字作為一個地址來調用connect與服務器建立連接。一旦建立了連接,就可以像使用底層文件描述符那樣來用套接字進行雙向的數據通信。?

TCP協議:

服務器端:tcp_server.c

?

?

[cpp]?view plaincopy
  1. #include?<stdio.h>??
  2. #include?<sys/types.h>??
  3. #include?<sys/socket.h>??
  4. #include?<netinet/in.h>??
  5. #include?<arpa/inet.h>??
  6. ??
  7. int?main(int?argc,?char?*argv[])??
  8. {??
  9. ????int?server_sockfd;//服務器端套接字??
  10. ????int?client_sockfd;//客戶端套接字??
  11. ????int?len;??
  12. ????struct?sockaddr_in?my_addr;???//服務器網絡地址結構體??
  13. ????struct?sockaddr_in?remote_addr;?//客戶端網絡地址結構體??
  14. ????int?sin_size;??
  15. ????char?buf[BUFSIZ];??//數據傳送的緩沖區??
  16. ????memset(&my_addr,0,sizeof(my_addr));?//數據初始化--清零??
  17. ????my_addr.sin_family=AF_INET;?//設置為IP通信??
  18. ????my_addr.sin_addr.s_addr=INADDR_ANY;//服務器IP地址--允許連接到所有本地地址上??
  19. ????my_addr.sin_port=htons(8000);?//服務器端口號??
  20. ??????
  21. ????/*創建服務器端套接字--IPv4協議,面向連接通信,TCP協議*/??
  22. ????if((server_sockfd=socket(PF_INET,SOCK_STREAM,0))<0)??
  23. ????{????
  24. ????????perror("socket");??
  25. ????????return?1;??
  26. ????}??
  27. ???
  28. ????????/*將套接字綁定到服務器的網絡地址上*/??
  29. ????if?(bind(server_sockfd,(struct?sockaddr?*)&my_addr,sizeof(struct?sockaddr))<0)??
  30. ????{??
  31. ????????perror("bind");??
  32. ????????return?1;??
  33. ????}??
  34. ??????
  35. ????/*監聽連接請求--監聽隊列長度為5*/??
  36. ????listen(server_sockfd,5);??
  37. ??????
  38. ????sin_size=sizeof(struct?sockaddr_in);??
  39. ??????
  40. ????/*等待客戶端連接請求到達*/??
  41. ????if((client_sockfd=accept(server_sockfd,(struct?sockaddr?*)&remote_addr,&sin_size))<0)??
  42. ????{??
  43. ????????perror("accept");??
  44. ????????return?1;??
  45. ????}??
  46. ????printf("accept?client?%s/n",inet_ntoa(remote_addr.sin_addr));??
  47. ????len=send(client_sockfd,"Welcome?to?my?server/n",21,0);//發送歡迎信息??
  48. ??????
  49. ????/*接收客戶端的數據并將其發送給客戶端--recv返回接收到的字節數,send返回發送的字節數*/??
  50. ????while((len=recv(client_sockfd,buf,BUFSIZ,0))>0))??
  51. ????{??
  52. ????????buf[len]='/0';??
  53. ????????printf("%s/n",buf);??
  54. ????????if(send(client_sockfd,buf,len,0)<0)??
  55. ????????{??
  56. ????????????perror("write");??
  57. ????????????return?1;??
  58. ????????}??
  59. ????}??
  60. ????close(client_sockfd);??
  61. ????close(server_sockfd);??
  62. ????????return?0;??
  63. }??

?

?

?

?

TCP協議:

?

客戶端:tcp_client.c

?

[c-sharp]?view plaincopy
  1. #include?<stdio.h>??
  2. #include?<sys/types.h>??
  3. #include?<sys/socket.h>??
  4. #include?<netinet/in.h>??
  5. #include?<arpa/inet.h>??
  6. ??
  7. int?main(int?argc,?char?*argv[])??
  8. {??
  9. ????int?client_sockfd;??
  10. ????int?len;??
  11. ????struct?sockaddr_in?remote_addr;?//服務器端網絡地址結構體??
  12. ????char?buf[BUFSIZ];??//數據傳送的緩沖區??
  13. ????memset(&remote_addr,0,sizeof(remote_addr));?//數據初始化--清零??
  14. ????remote_addr.sin_family=AF_INET;?//設置為IP通信??
  15. ????remote_addr.sin_addr.s_addr=inet_addr("127.0.0.1");//服務器IP地址??
  16. ????remote_addr.sin_port=htons(8000);?//服務器端口號??
  17. ??????
  18. ????/*創建客戶端套接字--IPv4協議,面向連接通信,TCP協議*/??
  19. ????if((client_sockfd=socket(PF_INET,SOCK_STREAM,0))<0)??
  20. ????{??
  21. ????????perror("socket");??
  22. ????????return?1;??
  23. ????}??
  24. ??????
  25. ????/*將套接字綁定到服務器的網絡地址上*/??
  26. ????if(connect(client_sockfd,(struct?sockaddr?*)&remote_addr,sizeof(struct?sockaddr))<0)??
  27. ????{??
  28. ????????perror("connect");??
  29. ????????return?1;??
  30. ????}??
  31. ????printf("connected?to?server/n");??
  32. ????len=recv(client_sockfd,buf,BUFSIZ,0);//接收服務器端信息??
  33. ?????????buf[len]='/0';??
  34. ????printf("%s",buf);?//打印服務器端信息??
  35. ??????
  36. ????/*循環的發送接收信息并打印接收信息--recv返回接收到的字節數,send返回發送的字節數*/??
  37. ????while(1)??
  38. ????{??
  39. ????????printf("Enter?string?to?send:");??
  40. ????????scanf("%s",buf);??
  41. ????????if(!strcmp(buf,"quit")??
  42. ????????????break;??
  43. ????????len=send(client_sockfd,buf,strlen(buf),0);??
  44. ????????len=recv(client_sockfd,buf,BUFSIZ,0);??
  45. ????????buf[len]='/0';??
  46. ????????printf("received:%s/n",buf);??
  47. ????}??
  48. ????close(client_sockfd);//關閉套接字??
  49. ?????????return?0;??
  50. }??

?

?

UDP協議:

服務器端:udp_server.c

?

?

[cpp]?view plaincopy
  1. #include?<stdio.h>??
  2. #include?<sys/types.h>??
  3. #include?<sys/socket.h>??
  4. #include?<netinet/in.h>??
  5. #include?<arpa/inet.h>??
  6. ??
  7. int?main(int?argc,?char?*argv[])??
  8. {??
  9. ????int?server_sockfd;??
  10. ????int?len;??
  11. ????struct?sockaddr_in?my_addr;???//服務器網絡地址結構體??
  12. ?????????struct?sockaddr_in?remote_addr;?//客戶端網絡地址結構體??
  13. ????int?sin_size;??
  14. ????char?buf[BUFSIZ];??//數據傳送的緩沖區??
  15. ????memset(&my_addr,0,sizeof(my_addr));?//數據初始化--清零??
  16. ????my_addr.sin_family=AF_INET;?//設置為IP通信??
  17. ????my_addr.sin_addr.s_addr=INADDR_ANY;//服務器IP地址--允許連接到所有本地地址上??
  18. ????my_addr.sin_port=htons(8000);?//服務器端口號??
  19. ??????
  20. ????/*創建服務器端套接字--IPv4協議,面向無連接通信,UDP協議*/??
  21. ????if((server_sockfd=socket(PF_INET,SOCK_DGRAM,0))<0)??
  22. ????{????
  23. ????????perror("socket");??
  24. ????????return?1;??
  25. ????}??
  26. ???
  27. ????????/*將套接字綁定到服務器的網絡地址上*/??
  28. ????if?(bind(server_sockfd,(struct?sockaddr?*)&my_addr,sizeof(struct?sockaddr))<0)??
  29. ????{??
  30. ????????perror("bind");??
  31. ????????return?1;??
  32. ????}??
  33. ????sin_size=sizeof(struct?sockaddr_in);??
  34. ????printf("waiting?for?a?packet.../n");??
  35. ??????
  36. ????/*接收客戶端的數據并將其發送給客戶端--recvfrom是無連接的*/??
  37. ????if((len=recvfrom(server_sockfd,buf,BUFSIZ,0,(struct?sockaddr?*)&remote_addr,&sin_size))<0)??
  38. ????{??
  39. ????????perror("recvfrom");???
  40. ????????return?1;??
  41. ????}??
  42. ????printf("received?packet?from?%s:/n",inet_ntoa(remote_addr.sin_addr));??
  43. ????buf[len]='/0';??
  44. ????printf("contents:?%s/n",buf);??
  45. ????close(server_sockfd);??
  46. ????????return?0;??
  47. }??

?

?

客戶端:udp_client.c

?

[cpp]?view plaincopy
  1. #include?<stdio.h>??
  2. #include?<sys/types.h>??
  3. #include?<sys/socket.h>??
  4. #include?<netinet/in.h>??
  5. #include?<arpa/inet.h>??
  6. ??
  7. int?main(int?argc,?char?*argv[])??
  8. {??
  9. ????int?client_sockfd;??
  10. ????int?len;??
  11. ????????struct?sockaddr_in?remote_addr;?//服務器端網絡地址結構體??
  12. ????int?sin_size;??
  13. ????char?buf[BUFSIZ];??//數據傳送的緩沖區??
  14. ????memset(&remote_addr,0,sizeof(remote_addr));?//數據初始化--清零??
  15. ????remote_addr.sin_family=AF_INET;?//設置為IP通信??
  16. ????remote_addr.sin_addr.s_addr=inet_addr("127.0.0.1");//服務器IP地址??
  17. ????remote_addr.sin_port=htons(8000);?//服務器端口號??
  18. ??
  19. ?????????/*創建客戶端套接字--IPv4協議,面向無連接通信,UDP協議*/??
  20. ????if((client_sockfd=socket(PF_INET,SOCK_DGRAM,0))<0)??
  21. ????{????
  22. ????????perror("socket");??
  23. ????????return?1;??
  24. ????}??
  25. ????strcpy(buf,"This?is?a?test?message");??
  26. ????printf("sending:?'%s'/n",buf);??
  27. ????sin_size=sizeof(struct?sockaddr_in);??
  28. ??????
  29. ????/*向服務器發送數據包*/??
  30. ????if((len=sendto(client_sockfd,buf,strlen(buf),0,(struct?sockaddr?*)&remote_addr,sizeof(struct?sockaddr)))<0)??
  31. ????{??
  32. ????????perror("recvfrom");???
  33. ????????return?1;??
  34. ????}??
  35. ????close(client_sockfd);??
  36. ????return?0;??
  37. }??

??

?

?

socket函數API.cpp

?

htons();//將short類型的值從主機字節序轉換為網絡字節序
inet_addr();//將IP地址字符串轉換為long類型的網絡字節序
gethostbyname();//獲得與該域名對應的IP地址
inet_ntoa();//將long類型的網絡字節序轉換成IP地址字符串


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/383946.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/383946.shtml
英文地址,請注明出處:http://en.pswp.cn/news/383946.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

哈希表2

哈希表的初始化 void HashInit(HashTable* ht, HashFunc func) {if(ht NULL){return;}ht -> size 0;ht -> func func;size_t i 0;for(; i < MaxSize; i){ht -> data[i] NULL;} } 哈希表的結點創建 HashElem* CreateHashElemNode(KeyType key, ValueType va…

位圖

相關數據結構 typedef uint64_t BitmapType;#define BITMAPMAXSIZE 1000 //位圖所能容納的位數typedef struct Bitmap {uint64_t* data;uint64_t capacity; }Bitmap; 初始化 void BitmapInit(Bitmap* bm, uint64_t capacity) {if(bm NULL){return;}//當capacity 100, 2個元…

C++中的inline用法

https://www.cnblogs.com/fnlingnzb-learner/p/6423917.html 1. 引入inline關鍵字的原因 在c/c中&#xff0c;為了解決一些頻繁調用的小函數大量消耗棧空間&#xff08;棧內存&#xff09;的問題&#xff0c;特別的引入了inline修飾符&#xff0c;表示為內聯函數。 棧空間就是指…

UVa1262

算是一個模擬吧 #include<cstdio> #include<cstring> #include<algorithm> #include<climits> #include<cctype> #include<queue> #include<set> #include<vector>using namespace std;typedef long long ll; const int INF…

一個Linux下C線程池的實現

http://blog.csdn.net/zouxinfox/article/details/3560891 什么時候需要創建線程池呢&#xff1f;簡單的說&#xff0c;如果一個應用需要頻繁的創建和銷毀線程&#xff0c;而任務執行的時間又非常短&#xff0c;這樣線程創建和銷毀的帶來的開銷就不容忽視&#xff0c;這時也是線…

Gym100917 A - Abstract Picture

模擬賽的時候看這道題沒有什么頭緒&#xff0c;當時有點暈&#xff0c;感冒還沒有好&#xff0c;回來以后瞟了一眼題解就明白了&#xff0c;自己實現了一下&#xff0c;也沒有很復雜。大概的思路就像拓撲排序一樣&#xff0c;需要理解因為涂的是有順序的&#xff0c;所以我們總…

linux進程通信---幾個發送信號的函數(kill,raise,alarm,pause)

http://blog.csdn.net/zzyoucan/article/details/9235685 信號&#xff1a;信號是unix中最古老的進程通信的一種方式&#xff0c;他是軟件層次上對中斷機制的模擬&#xff0c;是一種異步通信方式&#xff0c;信號可以實現用戶空間進程和內核空間進程的交互&#xff0c;內核進程…

數據庫以及表的基本操作

一.數據庫的操作 create database[if not exists]數據庫名; 創建一個名字為company2的使用utf8忽略大小寫的數據庫 create database company charsetutf8 collate utf8_general_ci; 創建一個數據庫區分大小寫 create database company1 charsetutf8 collate utf8_general_bin;…

linux 網絡編程:使用兩線程實現socket同時收發數據

http://blog.csdn.net/li_wen01/article/details/52665505 工作中最近有使用到socket 向客戶端同時發送和接收數據&#xff0c;因為是嵌入式linux設備&#xff0c;且要求只能同時一個客戶端連接該端口。考慮到節省系統資源&#xff0c;只創建了兩個線程分別實現服務端的收發數據…

CF Gym102059 H. Fractions

題目要求找到給定區間的化簡后分子分母的和小于1000的數字的個數 我的想法是先找到所有的滿足要求的最簡分數(總數不超過1e6,而且遠小于),然后對詢問查找每個最簡分數出現的次數. #include<cstdio> #include<cstring> #include<algorithm> #include<cli…

C語言calloc()函數:分配內存空間并初始化

http://c.biancheng.net/cpp/html/134.html 頭文件&#xff1a;#include <stdlib.h> calloc() 函數用來動態地分配內存空間并初始化為 0&#xff0c;其原型為&#xff1a; void* calloc (size_t num, size_t size); calloc() 在內存中動態地分配 num 個長度為 siz…

CF Gym100917 C

要找到和為給定值的所有的等比數列. 1肯定是要特判一下. 我的想法是先找到所有等比為1的,等比為1就是將這個數分為相同的一些數,總共就是這個數的所有約數個數減一(有一個約數為1,題目要求至少分成兩個數). 對于其他的等比不為1 的,用等比數列的求和公式暴力一發就行了. #i…

多路轉接select1

高級IO 通常情況下所有的 IO 都可以分為兩步來完成, 第一步等待, 第二步數據搬遷, 為了提高 IO 效率通常所運用的方法就是減少等待的時間 舉個釣魚的例子 現在有五個人張三, 李四, 王五, 趙六, 錢七. 它們五個人來到湖邊來釣魚. 而它們五個人的釣魚方各不相同. 張三釣魚方法…

UVa11181

題目要求條件概率,用貝葉斯公式我們很容易得到我們需要求r個人買東西的概率和每個人買東西的條件下其他r-1個人買東西的概率.我們遞歸枚舉,每當枚舉到r個人買東西的時候,我們加入到r個人買東西的概率中(全概率公式),然后對于這r個人,除去自己買東西的概率就是其他r-1個人買東西…

Linux epoll模型

http://www.cnblogs.com/venow/archive/2012/11/30/2790031.html 定義&#xff1a; epoll是Linux內核為處理大批句柄而作改進的poll&#xff0c;是Linux下多路復用IO接口select/poll的增強版本&#xff0c;它能顯著的減少程序在大量并發連接中只有少量活躍的情況下的系統CPU利…

UVa11572

書上把這種問題叫做滑動窗口問題. 我的想法是先進行離散化,然后用一個數組記錄元素出現的位置,如果判斷某個元素已經出現,就將左端點移到上次出現的位置的后面.每次出現重復元素的時候判斷一下答案.我覺得這樣的復雜度是最低的. #include<cstdio> #include<cstring&…

Linux IO模式及 select、poll、epoll詳解

https://segmentfault.com/a/1190000003063859 同步IO和異步IO&#xff0c;阻塞IO和非阻塞IO分別是什么&#xff0c;到底有什么區別&#xff1f;不同的人在不同的上下文下給出的答案是不同的。所以先限定一下本文的上下文。 本文討論的背景是Linux環境下的network IO。一 概念…

mysql思維導圖

后期會不斷進行更新

CF Gym 101630 B Box

題目的意思大概就是給一個長方體的長寬高,問他能不能用一個w*h的紙剪出來,就是說展開圖的長寬能不能比給定的小. 題目給了11中展開圖的拓撲結構,我覺得這個很關鍵,要是題目沒有給這個我可能想不到那么全面,不過題目已經給了我就分析那11個圖形,發現展開圖的長寬大概分為三類 …

C++第一節課

C數據類型 幾個概念 命名空間是C標準庫引入的,其中命名空間可以解決變量沖突問題,當出現局部變量和全局變量同名的時候, 局部變量優先被訪問.同時命名空間的格式如同一下代碼 namespace name1 { int a 0; }namespace name2 { int a 2; } 注意C中的所有組件都是在一個叫做s…