Linux 網路程式設計 TCP

2021-05-28 05:18:49 字數 4538 閱讀 4936

一、tcp通訊步驟

tcp伺服器部分:

1、呼叫函式socket(),建立乙個socket

2、設定sockaddr_in資訊,如要連線伺服器的ip和埠等屬性

3、呼叫函式bind(),繫結ip位址、埠等資訊到socket上

4、呼叫函式listen(),設定允許的最大連線數

5、呼叫函式accept(),等待來自客戶端的連線請求

6、呼叫函式send() 和 recv() 或者 read() 和 write() ,收發資料

7、呼叫close(),關閉網路連線

tcp客戶端部分:

1、呼叫函式socket(),建立乙個socket

2、設定sockaddr_in資訊,如要連線伺服器的ip和埠等屬性

3、呼叫函式connect(),連線伺服器

4、呼叫函式send() 和 recv() 或者 read() 和 write() ,收發資料

5、呼叫close(),關閉網路連線

從整體上看:

服務端: 

1、建立socket

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

pf_inet / af_inet ipv4網路協議;

pf_unix / pf_local / af_unix / af_local unix 程序通訊協議

type為傳輸型別:

sock_stream 提供雙向連續且可信賴的資料流,即tcp。

sock_dgram 使用不連續不可信賴的資料報連線,即udp。

protocol用來指定socket所使用的傳輸協議編號,通常設為0即可。

成功則返回新的socket處理**,失敗返回-1。

2、sockaddr_in 結構體資訊填充

struct sockaddr_in

0、將結構體初始化

void bzero(void *s,int n)

標頭檔案為。bzero()會將引數s所指的記憶體區域前n個位元組,全部設為零值。相當於呼叫memset((void*)s,0,size_tn);

1、sin_family:

協議型別與socket的domain相同。如:pf_inet

2、sin_port:

unsigned short int htons(unsigned short int hostshort);

htons()用來將引數指定的16位hostshort轉換成網路字元順序。返回對應的網路字元順序。

3、sin_addr:設定的是sin_addr.s_addr

unsigned long int inet_addr(const char *cp);

inet_addr()用來將引數cp所指的網路位址字串轉換成網路所使用的二進位制數字。網路位址字串是以數字和點組成的字串,例如:「127.0.0.1」。成功則返回對應的網路二進位制的數字,失敗返回-1。

unsigned long int htonl(unsigned long int hostlong);

htonl()用來將引數指定的32位hostlong 轉換成網路字元順序。返回對應的網路字元順序。通常為inaddr_any。

inaddr_any就是指定位址為0.0.0.0的位址,表示所有位址。 一般來說,在各個系統中均定義成為0值。

3、bind資訊到socket

int bind(int sockfd,struct sockaddr * my_addr,int addrlen);

sockfd為socket函式的返回值。

my_addr 為剛才填寫的結構體,要型別轉換 (sa *)&myadd。

addrlen為結構體的大小,用sizeof函式算。

成功返回0,失敗返回-1。

4、listen設定連線數

int listen(int sockfd,int backlog);

listen()用來設定ssockfd的最大連線數(backlog),如果連線數目達此上限則client端將收到econnrefused的錯誤。listen()並未開始接收連線,只是設定socket為listen模式,真正接收client端連線的是accept()。成功則返回0,失敗返回-1。

5、accept等待連線請求

int accept(int socketfd,struct sockaddr * addr,int * addrlen);

accept()用來接受引數socketfd連線。當有連線進來時accept()會返回乙個新的socket處理**,往後的資料傳送與讀取就是經由新的socket處理,而原來引數socketfd能繼續使用accept()來接受新的連線要求。

連線成功時,引數addr所指的結構會被系統填入遠端主機的位址資料。

addrlen為scokaddr的結構長度的指標

成功則返回新的socket處理**,相當於檔案操作符,失敗返回-1。

客戶端:

3、connect連線

int connect (int sockfd,struct sockaddr * serv_addr,int addrlen);

用來將引數sockfd的socket連至引數serv_addr指定的網路位址。引數addrlen為sockaddr的結構長度。

成功則返回0,失敗返回-1

二、舉例

//server

#include#include#include#include#include#include#include#includeint main(int argc,char *argv)

if((sockfd=socket(pf_inet,sock_stream,0))<0)

bzero(&sev_addr,sizeof(struct sockaddr_in));

sev_addr.sin_family = pf_inet;

sev_addr.sin_port = htons(8888);

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

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

if(listen(sockfd,5)<0)

while(1)

printf("the %s is conneted!\n",inet_ntoa(new_addr.sin_addr));

memset(buff,'\0',sizeof(buff));

if((nbytes=read(new_fd,buff,1024)) == -1)

printf("read over the nbytes is %d\n",nbytes);

buff[nbytes]='\0';

printf("server receive the message: %s",buff);

close(new_fd);

printf("exit.....\n");}}

//client

#include#include#include#include#include#include#include#includeint main(int argc,char *argv)

if((sockfd=socket(pf_inet,sock_stream,0))<0)

bzero(&clin_addr,sizeof(struct sockaddr_in));

clin_addr.sin_family = pf_inet;

clin_addr.sin_port = htons(8888);

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

if(connect(sockfd,(struct sockaddr*)&clin_addr,sizeof(struct sockaddr_in))<0)

memset(buff,'\0',1024);

fgets(buff,1024,stdin);

write(sockfd,buff,strlen(buff));

close(sockfd);

printf("client will exit!\n");

return 0;

}

Linux 網路程式設計(TCP)

include include include include include include include include int main int argc,char argv bzero server addr,sizeof struct sockaddr in server addr.si...

linux網路程式設計 初探TCP

伺服器端等待客戶端連線,連線成功後,列印客戶端的ip和port,然後迴圈接收資料,緩衝區無資料就阻塞待待。include include include include include include include include include include define maxbuf 10 ...

Linux下TCP網路程式設計流程

常見的兩種模型 c s模型 客戶端 伺服器端 和ptp 點對點 模型。下面為tcp網路流程程式設計兩台主機之間資料傳送的具體 示例。示例 檔案server.c include include include include include include include include void m...