Linux 網絡編程——TCP編程之客戶端

一轩缤、TCP概述
TCP(Transmission Control Protocol 傳輸控制協議)是一種面向連接的虏冻、可靠的底循、基于字節(jié)流的傳輸層通信協議。

TCP 具有以下特點:1)電話系統(tǒng)服務模式的抽象2)每一次完整的數據傳輸都要經過建立連接、使用連接、終止連接的過程3)可靠[圖片上傳中丧叽。鸥鹉。撑帖。(1)]筐眷、出錯重傳、且每收到一個數據都要給出相應的確認垒手,保證數據傳輸的可靠性


二蒜焊、TCP 編程的 C/S 架構
基于 TCP 的網絡編程開發(fā)分為服務器端和客戶端兩部分,常見的核心步驟和流程如下:


三科贬、TCP 客戶端編程
對于 TCP 客戶端編程流程泳梆,有點類似于打電話過程:
1.找個可以通話的手機(socket() )
2.撥通對方號碼并確定對方是自己要找的人( connect() )
3.主動聊天( send() 或 write() )
4.或者,接收對方的回話( recv() 或read() )
5.通信結束后榜掌,雙方說再見掛電話(close() )

所需頭文件:#include <sys/socket.h>
int socket(int family,int type,int protocol);
功能:
創(chuàng)建一個用于網絡通信的 socket套接字(描述符)鸭丛,詳細用法,請看《套接的介紹》
參數:
family:本示例寫 AF_INET唐责,代表 IPv4
type:本示例寫 SOCK_STREAM鳞溉,代表 TCP 數據流
protocol:這里寫 0,設為 0 表示使用默認協議

返回值:
成功:套接字
失敗 < 0

int connect( int sockfd, const struct sockaddr addr, socklen_t len );
功能:
主動跟服務器建立連接鼠哥,
有點類似于*熟菲,我們給別人電話,主動撥對方的電話號碼朴恳,具體是怎么一個過程抄罕,請《connect()、listen()和accept()三者之間的關系于颖。

參數:
sockfd:socket()返回的套接字
addr:連接的服務器地址結構
len:地址結構體長度

返回值:
成功:0
失敶艋摺:-1

connect() 函數相當于撥號碼,只有撥通號碼并且確定對方是自己要找的人(三次握手)才能進行下一步的通信。

ssize_t send(int sockfd, const void* buf, size_t nbytes, int flags);
功能:
發(fā)送數據做入,最后一個參數為 0 時冒晰,可以用 write() 替代( send 等同于 write )。注意:不能用 TCP 協議發(fā)送 0 長度的數據包竟块。假如壶运,數據沒有發(fā)送成功,內核會自動重發(fā)浪秘。

參數:
sockfd: 已建立連接的套接字
buf: 發(fā)送數據的地址
nbytes: 發(fā)送緩數據的大小(以字節(jié)為單位)
flags: 套接字標志(常為 0)

返回值:
成功:成功發(fā)送的字節(jié)數
失敗 < 0

這里通過 Windows 的網絡調試助手和虛擬機中的 ubuntu 客戶端程序進行通信蒋情,網絡調試助手下載請點訪問密碼 d5f3

Windows 的網絡調試助手作為 TCP 服務器耸携,接收客戶端的請求棵癣,調試助手配置如下:


3.1-實例1:tcp 客戶端發(fā)送數據:代碼ubuntu中運行

#include <stdio.h>  
#include <unistd.h>  
#include <string.h>  
#include <stdlib.h>  
#include <arpa/inet.h>  
#include <sys/socket.h>  
#include <netinet/in.h>  
int main(int argc, charchar *argv[])  
{  
    unsigned short port = 8080;             // 服務器的端口號  
    charchar *server_ip = "10.221.20.24";       // 服務器ip地址  
      
    if( argc > 1 )       //函數傳參,可以更改服務器的ip地址                                   
    {         
        server_ip = argv[1];  
    }     
    if( argc > 2 )      //函數傳參夺衍,可以更改服務器的端口號                                     
    {  
        port = atoi(argv[2]);  
    }  
  
    int sockfd;  
    sockfd = socket(AF_INET, SOCK_STREAM, 0);// 創(chuàng)建通信端點:套接字  
    if(sockfd < 0)  
    {  
        perror("socket");  
        exit(-1);  
    }  
      
    // 設置服務器地址結構體  
    struct sockaddr_in server_addr;  
    bzero(&server_addr,sizeof(server_addr)); // 初始化服務器地址  
    server_addr.sin_family = AF_INET;   // IPv4  
    server_addr.sin_port = htons(port); // 端口  
    inet_pton(AF_INET, server_ip, &server_addr.sin_addr.s_addr);    // ip  
      
     // 主動連接服務器  
    int err_log = connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));       
    if(err_log != 0)  
    {  
        perror("connect");  
        close(sockfd);  
        exit(-1);  
    }  
      
    char send_buf[512] = {0};  
    printf("send data to %s:%d\n",server_ip,port);  
    while(1)  
    {  
        printf("send:");  
        fgets(send_buf,sizeof(send_buf),stdin); // 輸入內容  
        send_buf[strlen(send_buf)-1]='\0';  
        send(sockfd, send_buf, strlen(send_buf), 0);   // 向服務器發(fā)送信息  
    }  
  
    close(sockfd);  
      
    return 0;  
}  

運行結果:


3.2-實例2:tcp客戶端接收數據浙巫,代碼在ubuntu下運行

tcp接收數據會用到recv()
ssize_t recv(int sockfd, void *buf, size_t nbytes, int flags);
功能:
接收網絡數據,默認的情況下刷后,如果沒有接收到數據,這個函數會阻塞渊抄,直到有數據到來尝胆。

參數:
sockfd:套接字
buf:接收網絡數據的緩沖區(qū)的地址
nbytes:接收緩沖區(qū)的大小(以字節(jié)為單位)
flags:套接字標志(常為 0 )

返回值:
成功:成功接收的字節(jié)數
失敗 < 0

#include <stdio.h>  
#include <unistd.h>  
#include <string.h>  
#include <stdlib.h>  
#include <arpa/inet.h>  
#include <sys/socket.h>  
#include <netinet/in.h>  
int main(int argc, charchar *argv[])  
{  
    unsigned short port = 8080;             // 服務器的端口號  
    charchar *server_ip = "10.221.20.24";       // 服務器ip地址  
      
    if( argc > 1 )       //函數傳參护桦,可以更改服務器的ip地址                                   
    {         
        server_ip = argv[1];  
    }     
    if( argc > 2 )      //函數傳參含衔,可以更改服務器的端口號                                     
    {  
        port = atoi(argv[2]);  
    }  
  
    int sockfd;  
    sockfd = socket(AF_INET, SOCK_STREAM, 0);// 創(chuàng)建通信端點:套接字  
    if(sockfd < 0)  
    {  
        perror("socket");  
        exit(-1);  
    }  
      
    // 設置服務器地址結構體  
    struct sockaddr_in server_addr;  
    bzero(&server_addr,sizeof(server_addr)); // 初始化服務器地址  
    server_addr.sin_family = AF_INET;   // IPv4  
    server_addr.sin_port = htons(port); // 端口  
    //inet_pton(AF_INET, server_ip, &server_addr.sin_addr); // ip  
    server_addr.sin_addr.s_addr = inet_addr(server_ip);//與inet_pton等價  
      
     // 主動連接服務器  
    int err_log = connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));       
    if(err_log != 0)  
    {  
        perror("connect");  
        close(sockfd);  
        exit(-1);  
    }  
      
      
    printf("send data to %s:%d\n",server_ip,port);  
      
    char send_buf[512] = "this is send data";  
    printf("send data \"%s \" to %s:%d\n",send_buf,server_ip,port);  
    send(sockfd, send_buf, strlen(send_buf), 0);   // 向服務器發(fā)送信息  
      
    char recv_buf[512] = {0};  
    recv(sockfd, recv_buf, sizeof(send_buf), 0); // 接收數據  
    printf("%s\n", recv_buf);  
  
    close(sockfd);  
      
    return 0;  
}  

運行結果:


最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市二庵,隨后出現的幾起案子贪染,更是在濱河造成了極大的恐慌,老刑警劉巖催享,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件杭隙,死亡現場離奇詭異,居然都是意外死亡因妙,警方通過查閱死者的電腦和手機痰憎,發(fā)現死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來攀涵,“玉大人铣耘,你說我怎么就攤上這事∫怨剩” “怎么了蜗细?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長怒详。 經常有香客問我炉媒,道長踪区,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任橱野,我火速辦了婚禮朽缴,結果婚禮上,老公的妹妹穿的比我還像新娘水援。我一直安慰自己密强,他們只是感情好,可當我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布蜗元。 她就那樣靜靜地躺著或渤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪奕扣。 梳的紋絲不亂的頭發(fā)上薪鹦,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天,我揣著相機與錄音惯豆,去河邊找鬼池磁。 笑死,一個胖子當著我的面吹牛楷兽,可吹牛的內容都是我干的地熄。 我是一名探鬼主播,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼芯杀,長吁一口氣:“原來是場噩夢啊……” “哼端考!你這毒婦竟也來了?” 一聲冷哼從身側響起揭厚,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤却特,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后筛圆,有當地人在樹林里發(fā)現了一具尸體裂明,經...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年太援,在試婚紗的時候發(fā)現自己被綠了漾岳。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡粉寞,死狀恐怖尼荆,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情唧垦,我是刑警寧澤捅儒,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響巧还,放射性物質發(fā)生泄漏鞭莽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一麸祷、第九天 我趴在偏房一處隱蔽的房頂上張望澎怒。 院中可真熱鬧,春花似錦阶牍、人聲如沸喷面。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽惧辈。三九已至,卻和暖如春磕瓷,著一層夾襖步出監(jiān)牢的瞬間盒齿,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工困食, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留边翁,地道東北人。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓硕盹,卻偏偏與公主長得像符匾,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子莱睁,可洞房花燭夜當晚...
    茶點故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內容