精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

TCP實現(xiàn)服務器與客戶端的通信流程實例

C語言編程學習基地 ? 2018-04-06 11:49 ? 次閱讀

主要函數(shù):

------------------------------------------

//服務器端---服務器是一個被動的角色

1.socket //買一個手機

2.bind //SIM卡 綁定一個手機號(ip+port)

3.listen //待機(等待電話打入)

4.accept //接聽電話

5.read/write //通話

6.close //掛機

//客戶端---客戶端是一個主動發(fā)起請求的一端

1.socket //買一個手機

2.bind(可選的) //SIM卡(綁定號碼)

3.connect //撥打電話

4.read/write //通話

5.close //掛機

//1.socket ---- 插口

int socket(int domain, int type, int protocol);

功能: 創(chuàng)建通信的一端 (socket)

參數(shù):

@domain //"域" --范圍

AF_INET //IPV4 協(xié)議的通信

@type SOCK_STREAM //TCP (流式套接字)

@protocol 0 //LINUX下 流式套接字 ==>TCP

//協(xié)議

返回值:

成功 對應的socket文件描述符

失敗 返回-1

注意:

文件描述符:

實際上就是 創(chuàng)建好的 socket的一個標識符

//2.bind

int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

功能:

給指定的 socket 綁定地址信息

參數(shù):

@sockfd //表示操作的socket

@addr //填充的地址信息(ip + port)

@addrlen //地址信息結構體的大小

返回值:

成功 0

失敗 -1

//通用的地址結構

struct sockaddr {

sa_family_t sa_family; //AF_INET //IPV4的協(xié)議

char sa_data[14];//(ip+port)

}

//網絡通信的地址結構(internet)

struct sockaddr_in {

sa_family_t sin_family; /* address family: AF_INET */

in_port_t sin_port; /* port in network byte order */

struct in_addr sin_addr; /* internet address */

};

/* Internet address. */

struct in_addr {

uint32_t s_addr; /* address in network byte order */

};

//1.定義一個 地址結構體變量

struct sockaddr_in addr;

bzero(&addr,sizeof(addr)); //清0的函數(shù)

//2.之后進行信息填充

addr.sin_family = AF_INET;

addr.sin_port = htons(8888);

addr.sin_addr.s_addr = inet_addr("127.0.0.1");

//127.0.0.1 是回環(huán)測試的地址

//3.進行綁定

if(bind(sockfd,(struct sockaddr*)&addr,sizeof(addr)) < 0)

{

perror("bind fail");

return 0;

}

//3.listen --- 設置監(jiān)聽 ---作用:讓操作系統(tǒng)監(jiān)控是否有客戶端發(fā)起連接

int listen(int sockfd, int backlog);

功能:

設置監(jiān)聽

參數(shù):

@sockfd //監(jiān)聽套接字

@backlog //監(jiān)聽隊列的大小

返回值

成功 0

失敗 -1

listenfd

--------------監(jiān)聽隊列------------------

fd1 fd2 fd3 fd4

|

-|--------------------------------------

|

\---->建立好連接的套接字

accept函數(shù)獲取已連接的套接字 返回對應

的標識符

|--->后面的讀寫操作 都是通過這個標識符

進行的

-----------------------------------------------

accept(); //accept 從監(jiān)聽隊列中獲得已連接的的socket,返回一個標示符來表示已連接的socket

//后續(xù)通過已連接的socket進行通信

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

功能: 獲取連接

參數(shù):

@sockfd //監(jiān)聽套接字的fd(標識符)

@addr //來電顯示(保存對端的地址信息)(ip+port)

@addrlen //表示 addr 參數(shù)對應類型的大小,值結果參數(shù) --- 就是在用的時候,必須先賦一個初值,最后函數(shù)調用完成

//通過該參數(shù),返回一個結果值

返回值:

成功 已連接的socket的標識符

失敗 -1

//connect ---發(fā)起連接

int connect(

int sockfd, //表示 進行通信的 socket的標識符

const struct sockaddr *addr, //對端的地址信息(ip+port)

socklen_t addrlen); //表示的是 addr 參數(shù)類型的長度

參數(shù):

@sockfd //通過socket函數(shù)獲得的fd

@addr //服務器端的地址

@addrlen //參數(shù)addr類型的大小

//數(shù)據(jù)流向 fd --> buf (count 表示一次讀取多少個字節(jié))

ssize_t read(int fd, void *buf, size_t count);

//數(shù)據(jù)流向 buf--> fd (count 表示一次寫多少個字節(jié))

ssize_t write(int fd, const void *buf, size_t count);

參數(shù):

@fd 就是要操作的 socket對應的 標示符

@buf 保存數(shù)據(jù)的一塊內存首地址

@count 一次操作的字節(jié)數(shù)

confd

char buf[] = "hello QCXY\n";

write(confd,buf,strlen(buf)); //寫 數(shù)據(jù)到socket中

//讀數(shù)據(jù)出來

char rbuf[1024] = {0}; //表示申請了一塊1024個字節(jié)大小

//的內存空間

read(confd,rbuf,sizeof(rbuf)); //讀取數(shù)據(jù)

//練習:

實現(xiàn) 客戶端 向服務器發(fā)送數(shù)據(jù)

服務器回發(fā)數(shù)據(jù)的功能

client ----- server

scanf(); ---(1)----> read 之后printf

read <--(2)---- ? ? ? ? write

printf

循環(huán)做,結束條件

當客戶端輸入 "quit"字符串時 客戶端結束

怎么判斷客戶端讀到的是"quit"

c語言

"quit" == buf; (X) //不能這么寫

//字符串的比較函數(shù)

strcmp("quit",buf);

strncmp("quit",buf,4);

客戶端的程序:

#include

#include /* See NOTES */

#include

#include

#include

#include

#include

//./client 127.0.0.1 8888

int main(int argc, const char *argv[])

{

int fd;

int ret = 0;

char buf[1024] = {0};

char rbuf[1024] = {0};

//處理命令行參數(shù)

//1.socket(手機)

//2.bind(電話卡)

//3.connect (撥打電話)

//處理命令行參數(shù)

if(argc != 3)

{

printf("Usage: %s \n",argv[0]);

return -1;

}

//1.socket(手機)

fd = socket(AF_INET,SOCK_STREAM,0);

if(fd < 0) //出錯處理

{

perror("socket fail");

return -1;

}

printf("fd = %d\n",fd);

//2.bind(電話卡)---綁定的是客戶端自己的地址信息

//客戶端地址信息

//1.定義一個 地址結構體變量

struct sockaddr_in cli_addr;

bzero(&cli_addr,sizeof(cli_addr)); //清0的函數(shù)

//2.之后進行信息填充

cli_addr.sin_family = AF_INET;

cli_addr.sin_port = htons(7777);

cli_addr.sin_addr.s_addr = inet_addr(argv[1]);

if(bind(fd,(struct sockaddr*)&cli_addr,sizeof(cli_addr)) < 0)

{

perror("bind fail");

return -1;

}

//服務器端的地址信息

//1.定義一個 地址結構體變量

struct sockaddr_in addr;

bzero(&addr,sizeof(addr)); //清0的函數(shù)

//2.之后進行信息填充

addr.sin_family = AF_INET;

addr.sin_port = htons(atoi(argv[2]));

addr.sin_addr.s_addr = inet_addr(argv[1]);

//3.connect (撥打電話)

if(connect(fd,(struct sockaddr*)&addr,sizeof(addr))<0)

{

perror("connect fail");

return -1;

}

printf("connect success\n");

//通信過程

while(1)

{

//客戶端從鍵盤獲得數(shù)據(jù)

//數(shù)據(jù)流向stdin --> buf

fgets(buf,sizeof(buf),stdin); //stdin表示是從鍵盤獲得數(shù)據(jù)

//發(fā)送給服務器

write(fd,buf,strlen(buf));

//接受服務器回發(fā)的消息

ret = read(fd,rbuf,sizeof(rbuf));

//如果回發(fā)的消息是

//quit

//則結束

rbuf[ret] = '\0';

printf("rbuf = %s\n",rbuf);

if(strncmp("quit",buf,4) == 0)

{

close(fd);

break;

}

}

return 0;

}

服務端

#include

#include /* See NOTES */

#include

#include

#include

#include

//./server 127.0.0.1 8888

int main(int argc, const char *argv[])

{

int fd = 0;

int connfd = 0;

int ret = 0;

char buf[1024] = {0};

//處理命令行參數(shù)

if(argc != 3)

{

printf("Usage: %s \n",argv[0]);

return -1;

}

//1.socket 創(chuàng)建套接字

fd = socket(AF_INET,SOCK_STREAM,0);

if(fd < 0) //出錯處理

{

perror("socket fail");

return -1;

}

printf("fd = %d\n",fd);

//2.綁定

//1.準備地址信息

//2.綁定

//

//1.定義一個 地址結構體變量

struct sockaddr_in addr;

bzero(&addr,sizeof(addr)); //清0的函數(shù)

//2.之后進行信息填充

addr.sin_family = AF_INET;

addr.sin_port = htons(atoi(argv[2]));

addr.sin_addr.s_addr = inet_addr(argv[1]);

//127.0.0.1 是回環(huán)測試的地址

//3.進行綁定

if(bind(fd,(struct sockaddr*)&addr,sizeof(addr)) < 0)

{

perror("bind fail");

return 0;

}

printf("bind success\n");

//4.設置監(jiān)聽

if(listen(fd,5) < 0)

{

perror("listen fail");

return -1;

}

struct sockaddr_in peer_addr;

socklen_t addrlen = sizeof(peer_addr);

//5.獲取連接 -- 接聽電話

while(1) //可以不斷接受客戶端的請求

{

//connfd = accept(fd,NULL,NULL);

connfd = accept(fd,(struct sockaddr*)&peer_addr,&addrlen);

if(connfd < 0)

{

perror("accept fail");

return -1;

}

printf("connfd = %d\n",connfd);

printf("-----------------------\n");

printf("ip = %s\n",inet_ntoa(peer_addr.sin_addr));

printf("port = %d\n",ntohs(peer_addr.sin_port));

printf("-----------------------\n");

//通信過程

//效果實現(xiàn)數(shù)據(jù)回發(fā)

while(1)

{

//read 與 write 的返回值 大于0 時表示的是

//一次成功操作到的字節(jié)數(shù)

ret = read(connfd,buf,sizeof(buf));

//hello

buf[ret] = '\0'; //添加'\0'--轉換成字符串

printf("buf = %s\n",buf);//字符串打印 需要

//結束標志 '\0'

if(ret == 0 || strncmp(buf,"quit",4) == 0)

{

close(connfd);

break;

}

write(connfd,buf,ret);

}

} //telnet

return 0;

}

補充:

可以用如下函數(shù)替代read,write

ssize_t recv(int sockfd, void* buf,size_t len,int flags);

ssize_t send(int sockfd,const void *buf,size_t len,int flags);

@sockfd //進行操作的socket的文件描述符

@buf //保存數(shù)據(jù)的首地址

@len //一次操作的字節(jié)數(shù)

@flags //標志0--默認的操作方式(阻塞)

返回值:

成功 成功操作的字節(jié)數(shù)

失敗 -1&errno

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • TCP
    TCP
    +關注

    關注

    8

    文章

    1349

    瀏覽量

    78985
  • 客戶端
    +關注

    關注

    1

    文章

    290

    瀏覽量

    16661
  • 通信編程
    +關注

    關注

    0

    文章

    5

    瀏覽量

    2027

原文標題:C語言中如何實現(xiàn)網絡通信(流程實例)

文章出處:【微信號:cyuyanxuexi,微信公眾號:C語言編程學習基地】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    用labview做個服務器,和若干個客戶端同時進行TCP通信

    用labview做個服務器,和若干個客戶端同時進行TCP通信,有哪位高手做過的指點下小弟吧,不勝感激!
    發(fā)表于 05-21 19:01

    labview TCP客戶端

    最近在做一個labview 客戶端測試小程序,服務器采用MFC編寫,客戶端采用TCP偵聽函數(shù),通信可以連接,數(shù)據(jù)也正確,但是
    發(fā)表于 06-30 23:15

    【NanoPi NEO試用體驗】TCP通信客戶端程序

    不適合傳輸實時視頻這種數(shù)據(jù)量比較大的。通信雙方是基于C/S架構,這里使用電腦TCP助手作為服務器,NEO寫了客戶端的程序。雙方大致
    發(fā)表于 12-28 23:40

    labview-TCP客戶端服務器

    labview-TCP客戶端服務器一個服務器上位機,多個下位機客戶端
    發(fā)表于 03-26 16:58

    如何使用Socket實現(xiàn)UDP客戶端

    本教程介紹了如何利用socket 編程來實現(xiàn)一個 UDP 客戶端,與服務器進行通信。與開發(fā) TCP 客戶
    發(fā)表于 03-30 07:39

    Labview TCP服務器和多個客戶端問題

    我開啟一個Labview TCP服務器,與外部兩個TCP客戶端連接,兩個客戶端會定時給服務端發(fā)送
    發(fā)表于 04-13 18:43

    當WiFi信號變低時,服務器客戶端之間的TCP通信丟失,如何使客戶端重新連接?

    大家好, 當 WiFi 信號變低時,服務器客戶端之間的 TCP 通信丟失,比如超過 -80dBm。一旦客戶端斷開連接,它就無法重新連接并正
    發(fā)表于 05-15 07:31

    服務器客戶端之間的TCP通信丟失怎么處理?

    嗨, 當 WiFi 信號變低時,比如超過 -80dBm,我面臨服務器客戶端之間的 TCP 通信丟失。一旦客戶端斷開連接,它就無法重新連接并
    發(fā)表于 05-16 08:19

    網絡調試和串口調試集合UDP TCP客戶端TCP服務器端應用程序免費下載

    本文檔的主要內容詳細介紹的是網絡調試和串口調試集合UDP TCP客戶端TCP服務器端應用程序免費下載。
    發(fā)表于 08-30 08:00 ?16次下載
    網絡調試和串口調試集合UDP <b class='flag-5'>TCP</b><b class='flag-5'>客戶端</b>和<b class='flag-5'>TCP</b><b class='flag-5'>服務器端</b>應用程序免費下載

    ESP8266作為TCP客戶端連接TCP服務器和測試的實例資料說明

    本文檔的主要內容詳細介紹的是ESP8266作為TCP客戶端連接TCP服務器和測試的實例資料說明。
    發(fā)表于 06-06 17:51 ?8次下載
    ESP8266作為<b class='flag-5'>TCP</b><b class='flag-5'>客戶端</b>連接<b class='flag-5'>TCP</b><b class='flag-5'>服務器</b>和測試的<b class='flag-5'>實例</b>資料說明

    Linux下網絡編程TCP并發(fā)服務器TCP客戶端程序免費下載

    本文檔的主要內容詳細介紹的是Linux下網絡編程TCP并發(fā)服務器TCP客戶端程序免費下載
    發(fā)表于 01-08 15:12 ?9次下載
    Linux下網絡編程<b class='flag-5'>TCP</b>并發(fā)<b class='flag-5'>服務器</b>和<b class='flag-5'>TCP</b><b class='flag-5'>客戶端</b>程序免費下載

    STM32+LWIP服務器實現(xiàn)客戶端連接

    (UCOSIII版本) 的基礎上進行修改,實現(xiàn)客戶端連接的一個方法。1、TCP服務器創(chuàng)建過程建立一個TCP
    發(fā)表于 12-23 19:59 ?61次下載
    STM32+LWIP<b class='flag-5'>服務器</b><b class='flag-5'>實現(xiàn)</b>多<b class='flag-5'>客戶端</b>連接

    Linux下TCP網絡編程-創(chuàng)建服務器客戶端

    這篇文章介紹在Linux下的socket編程,完成TCP服務器客戶端的創(chuàng)建,實現(xiàn)數(shù)據(jù)通信
    的頭像 發(fā)表于 08-14 09:26 ?2419次閱讀
    Linux下<b class='flag-5'>TCP</b>網絡編程-創(chuàng)建<b class='flag-5'>服務器</b>與<b class='flag-5'>客戶端</b>

    基于LwIP的TCP客戶端設計

    上一篇我們基于LwIP協(xié)議棧的RAW API實現(xiàn)了一個TCP服務器的簡單應用,接下來一節(jié)我們來實現(xiàn)一個TCP
    的頭像 發(fā)表于 12-14 15:12 ?2239次閱讀
    基于LwIP的<b class='flag-5'>TCP</b><b class='flag-5'>客戶端</b>設計

    服務器Server和客戶端Client的區(qū)別

    例如在使用TCP通訊建立連接時采用客戶端服務器模式,這種模式又常常被稱為主從式架構,簡稱為C/S結構,屬于一種網絡通訊架構,將通訊的雙方以客戶端(Client )與
    的頭像 發(fā)表于 09-06 16:13 ?1326次閱讀
    <b class='flag-5'>服務器</b>Server和<b class='flag-5'>客戶端</b>Client的區(qū)別