linux tcp網(wǎng)絡(luò)通信

socket編程

  • socket編程的基本函數(shù)有socket()凿蒜、bind()禁谦、listen()、accept()废封、send()州泊、sendto()、recv()以及recvfrom()等漂洋,其中根據(jù)客戶端還是服務(wù)端遥皂,或者根據(jù)使用TCP協(xié)議還是UDP協(xié)議,這些函數(shù)的調(diào)用流程都有所區(qū)別刽漂。
    1.socket():該函數(shù)用于建立一個(gè)socket連接(即創(chuàng)建一個(gè)套接字)演训,可指定socket類型等信息。在建立了socket連接之后贝咙,可對(duì)sockaddr或sockaddr_in結(jié)構(gòu)進(jìn)行初始化样悟,以保存所建立的socket地址信息。



    2.bind():該函數(shù)是用于將socket套接字與本地IP地址及端口號(hào)綁定庭猩,若綁定其他IP地址則不能成功窟她。另外,它主要用于服務(wù)器端蔼水,而在客戶端則無(wú)必要震糖。



    3.listen():在服務(wù)端程序成功建立套接字和與地址進(jìn)行綁定之后,還需要準(zhǔn)備在該套接字上接收新的連接請(qǐng)求趴腋。此時(shí)調(diào)用listen()函數(shù)來(lái)創(chuàng)建一個(gè)等待隊(duì)列吊说,在其中存放未處理的客戶端連接請(qǐng)求。

    4.accept():服務(wù)端程序調(diào)用listen()函數(shù)創(chuàng)建等待隊(duì)列之后于样,調(diào)用accept()函數(shù)等待并接收客戶端的連接請(qǐng)求疏叨。它通常從由listen()所創(chuàng)建的等待隊(duì)列中取出第一個(gè)未處理的連接請(qǐng)求潘靖。

    5.connect():該函數(shù)在TCP中是用于bind()的之后的client端穿剖,用于與服務(wù)器端建立連接。



    6.send()和recv():這兩個(gè)函數(shù)分別用于發(fā)送和接收數(shù)據(jù)卦溢,用在TCP中糊余。


    7.sendto()和recvfrom():這兩個(gè)函數(shù)的作用與send()和recv()函數(shù)類似,可以用在TCP和UDP中单寂。當(dāng)用在TCP時(shí)贬芥,后面的幾個(gè)與地址有關(guān)參數(shù)不起作用,函數(shù)作用等同于send()和recv()宣决;主要用在UDP時(shí)蘸劈,這兩個(gè)函數(shù)可以自動(dòng)尋找指定地址并進(jìn)行連接。

代碼實(shí)戰(zhàn)

/*server.c*/
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>

#define PORT            4321
#define BUFFER_SIZE        1024
#define MAX_QUE_CONN_NM   5

int main()
{
     struct sockaddr_in server_sockaddr,client_sockaddr;
     int sin_size,recvbytes,sendbytes;
     int sockfd, client_fd;
     char buf[BUFFER_SIZE];
     
     /*建立socket連接*/
     if ((sockfd = socket(AF_INET,SOCK_STREAM,0))== -1)
     {
          perror("socket");
          exit(1);
     }
     printf("Socket id = %d\n",sockfd);
     
     /*設(shè)置sockaddr_in 結(jié)構(gòu)體中相關(guān)參數(shù)*/
     server_sockaddr.sin_family = AF_INET;
     server_sockaddr.sin_port = htons(PORT);
     server_sockaddr.sin_addr.s_addr = INADDR_ANY;
     bzero(&(server_sockaddr.sin_zero), 8);
     
     int i = 1;/* 允許重復(fù)使用本地地址與套接字進(jìn)行綁定 */
     setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
     
     /*綁定函數(shù)bind()*/
     if (bind(sockfd, (struct sockaddr *)&server_sockaddr,sizeof(struct sockaddr)) == -1)
     {
          perror("bind");
          exit(1);
     }
     printf("Bind success!\n");
     
     /*調(diào)用listen()函數(shù)尊沸,創(chuàng)建未處理請(qǐng)求的隊(duì)列*/
     if (listen(sockfd, MAX_QUE_CONN_NM) == -1)
     {
          perror("listen");
          exit(1);
     }
     printf("Listening....\n");
     
     /*調(diào)用accept()函數(shù)威沫,等待客戶端的連接*/
     sin_size=sizeof(struct sockaddr);
     if ((client_fd = accept(sockfd, 
                  (struct sockaddr *)&client_sockaddr, &sin_size)) == -1)
     {
          perror("accept");
          exit(1);
     }
     
     /*調(diào)用recv()函數(shù)接收客戶端的請(qǐng)求*/
    while(1)
    {       
         memset(buf , 0, sizeof(buf));
         if ((recvbytes = recv(client_fd, buf, BUFFER_SIZE, 0)) == -1)
         {
              perror("recv");
              exit(1);
         }
         printf("Received a message: %s\n", buf);
    }
     close(sockfd);
     exit(0);
}
/*client.c*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>

#define PORT   8888
#define BUFFER_SIZE 1024

int main(int argc, char *argv[])
{
     int sockfd,sendbytes;
     char buf[BUFFER_SIZE];
     struct hostent *host;
     struct sockaddr_in serv_addr;
     
     if(argc < 3)
     {
          fprintf(stderr,"USAGE: ./client Hostname(or ip address) Text\n");
          exit(1);
     }
     
     /*地址解析函數(shù)*/
     if ((host = gethostbyname(argv[1])) == NULL)
     {
          perror("gethostbyname");
          exit(1);
     }
     
     memset(buf, 0, sizeof(buf));
     sprintf(buf, "%s", argv[2]);
     //sprintf(buf, "%s", "This is client,I want to connect!");
     
     /*創(chuàng)建socket*/
     if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
     {
          perror("socket");
          exit(1);
     }
     
     /*設(shè)置sockaddr_in 結(jié)構(gòu)體中相關(guān)參數(shù)*/
     serv_addr.sin_family = AF_INET;
     serv_addr.sin_port = htons(PORT);
     serv_addr.sin_addr=*((struct in_addr *)host->h_addr);
     bzero(&(serv_addr.sin_zero), 8);
     
     /*調(diào)用connect函數(shù)主動(dòng)發(fā)起對(duì)服務(wù)器端的連接*/
     if(connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(struct sockaddr))== -1)
     {
          perror("connect failed!\n");
          exit(1);
     }
     /*發(fā)送消息給服務(wù)器端*/
     if ((sendbytes = send(sockfd, buf, strlen(buf), 0)) == -1)
     {
          perror("send");
          exit(1);
     }
     memset(buf , 0, sizeof(buf));
     close(sockfd);
     exit(0);
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末贤惯,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子棒掠,更是在濱河造成了極大的恐慌孵构,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,816評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件烟很,死亡現(xiàn)場(chǎng)離奇詭異颈墅,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)雾袱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)恤筛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人芹橡,你說(shuō)我怎么就攤上這事叹俏。” “怎么了僻族?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,300評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵粘驰,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我述么,道長(zhǎng)蝌数,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,780評(píng)論 1 285
  • 正文 為了忘掉前任度秘,我火速辦了婚禮顶伞,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘剑梳。我一直安慰自己唆貌,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布垢乙。 她就那樣靜靜地躺著锨咙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪追逮。 梳的紋絲不亂的頭發(fā)上酪刀,一...
    開(kāi)封第一講書(shū)人閱讀 50,084評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音钮孵,去河邊找鬼骂倘。 笑死,一個(gè)胖子當(dāng)著我的面吹牛巴席,可吹牛的內(nèi)容都是我干的历涝。 我是一名探鬼主播,決...
    沈念sama閱讀 39,151評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼荧库!你這毒婦竟也來(lái)了诱担?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,912評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤电爹,失蹤者是張志新(化名)和其女友劉穎蔫仙,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體丐箩,經(jīng)...
    沈念sama閱讀 44,355評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡摇邦,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了屎勘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片施籍。...
    茶點(diǎn)故事閱讀 38,809評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖概漱,靈堂內(nèi)的尸體忽然破棺而出丑慎,到底是詐尸還是另有隱情,我是刑警寧澤瓤摧,帶...
    沈念sama閱讀 34,504評(píng)論 4 334
  • 正文 年R本政府宣布竿裂,位于F島的核電站,受9級(jí)特大地震影響照弥,放射性物質(zhì)發(fā)生泄漏腻异。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評(píng)論 3 317
  • 文/蒙蒙 一这揣、第九天 我趴在偏房一處隱蔽的房頂上張望悔常。 院中可真熱鬧,春花似錦给赞、人聲如沸机打。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)残邀。三九已至,卻和暖如春障涯,著一層夾襖步出監(jiān)牢的瞬間罐旗,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,121評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工唯蝶, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人遗嗽。 一個(gè)月前我還...
    沈念sama閱讀 46,628評(píng)論 2 362
  • 正文 我出身青樓粘我,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子征字,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容