基於tcp(面向連線)的socket程式設計,分為伺服器端和客戶端
伺服器端的流程如下:
(1)建立套接字(socket)
(2)將套接字繫結到乙個本地位址和埠上(bind)
(3)將套接字設為監聽模式,準備接收客戶端請求(listen)
(4)等待客戶請求到來;當請求到來後,接受連線請求,返回乙個新的對應於此次連線的套接字(accept)
(5)用返回的套接字和客戶端進行通訊(send/recv)
(6)返回,等待另乙個客戶請求。
(7)關閉套接字。
客戶端的流程如下:
(1)建立套接字(socket)
(2)向伺服器發出連線請求(connect)
(3)和伺服器端進行通訊(send/recv)
(4)關閉套接字
下面通過乙個具體例子講解一下具體的過程和相關的函式,環境是suse linux。
#include
#include
#include
#include
#include
#include
#include
//#include
#include
//#include
#include
#include
/**
關於 sockaddr sockaddr_in socketaddr_un說明
*/
#define port 11910 //定義通訊埠
#define backlog 5 //定義偵聽佇列長度
#define buflen 1024
void process_conn_server(int s);
void sig_pipe(int signo);
int ss,sc; //ss為伺服器socket描述符,sc為某一客戶端通訊socket描述符
int main(int argc,char *ar**)
//註冊訊號
sighandler_t ret;
ret = signal(sigtstp,sig_pipe);
if(sig_err == ret)
else
printf("訊號掛接成功\n");
/******************bind()****************/
//初始化位址結構
memset(&server_addr,0,sizeof(server_addr));
server_addr.sin_family = af_inet; //協議族
server_addr.sin_addr.s_addr = htonl(inaddr_any); //本地位址
server_addr.sin_port = htons(port);
err = bind(ss,(struct sockaddr *)&server_addr,sizeof(sockaddr));
if(err<0)
/*****************listen()***************/
err = listen(ss,backlog); //設定監聽的佇列大小
if(err < 0)
/****************accept()***************/
/**
為類方便處理,我們使用兩個程序分別管理兩個處理:
1,伺服器監聽新的連線請求;2,以建立連線的c/s實現通訊
這兩個任務分別放在兩個程序中處理,為了防止失誤操作
在乙個程序中關閉 偵聽套接字描述符 另一程序中關閉
客戶端連線套接字描述符。注只有當所有套接字全都關閉時
當前連線才能關閉,fork呼叫的時候父程序與子程序有相同的
套接字,總共兩套,兩套都關閉掉才能關閉這個套接字
*/
for(;;)
else
//建立乙個子執行緒,用於與客戶端通訊
pid = fork();
//fork 呼叫說明:子程序返回 0 ;父程序返回子程序 id
if(pid == 0) //子程序,與客戶端通訊
else
}
}
/**
伺服器對客戶端連線處理過程;先讀取從客戶端傳送來的資料,
然後將接收到的資料的位元組的個數傳送到客戶端
*/
//通過套接字 s 與客戶端進行通訊
void process_conn_server(int s)
sprintf(buffer,"%d bytes altogether\n",size);
write(s,buffer,strlen(buffer)+1);
}
}
void sig_pipe(int signo)
}
客戶端**:
#include
#include
#include
#include
#include
//#include
#include
#include
#include
#include
#include //新增訊號處理 防止向已斷開的連線通訊
/**
訊號處理方式是:1,系統首先呼叫使用者在程序中註冊的函式,2,然後呼叫系統的預設
響應方式,此處我們可以註冊自己的訊號處理函式,在連線斷開時執行
*/
#define port 11910
#define buflen 1024
void process_conn_client(int s);
void sig_pipe(int signo); //使用者註冊的訊號函式,接收的是訊號值
int s; //全域性變數 , 儲存套接字描述符
int main(int argc,char *ar**)
printf("client : socket fd = %d\n", s);
//訊號處理函式 sigint 是當使用者按乙個 ctrl-c 建時傳送的訊號
ret = signal(sigtstp,sig_pipe);
if(sig_err == ret)
else
printf("訊號掛接成功\n") ;
/*******************connect()*********************/
//設定伺服器位址結構,準備連線到伺服器
memset(&server_addr,0,sizeof(server_addr));
server_addr.sin_family = af_inet;
server_addr.sin_port = htons(port);
server_addr.sin_addr.s_addr = htonl(inaddr_any);
/*將使用者數入對額字串型別的ip格式轉化為整型資料*/
//inet_pton(af_inet,ar**[1],&server_addr.sin_addr.s_addr);
printf("please input server ip address : \n");
read(0,server_ip,50);
//err = inet_pton(af_inet,server_ip,&server_addr.sin_addr.s_addr);
server_addr.sin_addr.s_addr = inet_addr(server_ip);
err = connect(s,(struct sockaddr *)&server_addr,sizeof(sockaddr));
if(err == 0)
else
//與伺服器端進行通訊
process_conn_client(s);
close(s);
}
void process_conn_client(int s)
}
}
void sig_pipe(int signo) //傳入套接字描述符
}
串列埠通訊簡單例項
前幾天製作了乙個基於win32控制台的串列埠通訊接收端的程式。今天利用mfc製作了乙個類似超級終端的應用程式。包含了傳送端和接收端。介面如下圖 關鍵 如下 button connect響應函式,開啟串列埠,配置串列埠引數,設定事件掩碼,建立接收端執行緒。void cmfc commdlg onbut...
TCP 通訊 簡記
1.客戶端向伺服器端傳送請求建立鏈結報文,資料 syn 1,ack 0 seq i 狀態 客戶端進入 syn send 2.伺服器端接收到,客戶端傳送的報文,返回統一鏈結確認報文 資料 syn 1,ack 1 ack i 1,seq j 狀態 伺服器端進入 syn rcvd 3.客戶端接受到伺服器端...
WCF通訊簡單示例
今天寫了乙個wcf demo,給大家分享,說明如下 服務介面類庫wcfservice.dll 服務實現類庫wcfservicimp.dll 服務宿主專案wcfhost 客戶端呼叫專案 wcftest 客戶端呼叫服務的時候,要引用介面類庫 wcfservice.dll 伺服器端宿主 public pa...