socket程式設計
(1)函式說明。
socket 程式設計的基本函式有 socket()、 bind()、 listen()、 accept()、 send()、 sendto()、 recv()以及 recvfrom()等,其中根據客戶端還是服務端,或者根據使用 tcp 協議還是 udp 協議,這些函式的呼叫流程都有所區別,這裡先對每個函式進行說明,再給出各種情況下使用的流程圖。
socket():該函式用於建立乙個 socket 連線,可指定 socket 型別等資訊。在建立了 socket 連線之後,可對 sockaddr 或 sockaddr_in 結構進行初始化,以保
存所建立的 socket 位址資訊。
bind():該函式是用於將本地 ip 位址繫結到埠號, 若繫結其他 ip 位址則不能成功。另外,它主要用於 tcp 的連線,而在 udp 的連線中則無必要。
listen():在服務端程式成功建立套接字和與位址進行繫結之後,還需要準備在該套接字上接收新的連線請求。此時呼叫 listen()函式來建立乙個等待佇列,在其中存放未處理的客戶端連線請求。
accept():服務端程式呼叫 listen()函式建立等待佇列之後,呼叫 accept()函式等待並接收客戶端的連線請求。它通常從由 bind()所建立的等待佇列中取出第乙個未處理的連線請求。
connect():該函式在 tcp 中是用於 bind()的之後的 client 端,用於與伺服器端建立連線,而在 udp 中由於沒有了 bind()函式,因此用 connect()有點類似 bind()函式的作用。
send()和 recv():這兩個函式分別用於傳送和接收資料,可以用在 tcp 中,也可以用在 udp 中。當用在 udp 時,可以在 connect()函式建立連線之後再用。
sendto()和 recvfrom():這兩個函式的作用與 send()和 recv()函式類似,也可以用在 tcp 和 udp 中。 當用在 tcp 時, 後面的幾個與位址有關引數不起作用,函式作用等同於 send()和 recv();當用在 udp 時,可以用在之前沒有使用connect()的情況下,這兩個函式可以自動尋找指定位址並進行連線。
(2)程式設計例項
該例項分為客戶端和伺服器端兩部分,其中伺服器端首先建立起 socket,然後與本地埠進行繫結, 接著就開始接收從客戶端的連線請求並建立與它的連線, 接下來,接收客戶端傳送的訊息。客戶端則在建立 socket 之後呼叫 connect()函式來建立連線。
伺服器端**:
#include #include #include #include #include #include #include #include #define port 4321
#define buffer_size 1024
#define max_que_conn_nm 5
int main()
printf("socket id = %d\n",sockfd);
/*設定 sockaddr_in 結構體中相關引數*/
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;/* 允許重複使用本地位址與套接字進行繫結 */
setsockopt(sockfd, sol_socket, so_reuseaddr, &i, sizeof(i));
/*繫結函式 bind()*/
if (bind(sockfd, (struct sockaddr *)&server_sockaddr,
sizeof(struct sockaddr)) == -1)
printf("bind success!\n");
/*呼叫 listen()函式,建立未處理請求的佇列*/
if (listen(sockfd, max_que_conn_nm) == -1)
printf("listening....\n");
/*呼叫 accept()函式,等待客戶端的連線*/
if ((client_fd = accept(sockfd,
(struct sockaddr *)&client_sockaddr, &sin_size)) == -1)
/*呼叫 recv()函式接收客戶端的請求*/
memset(buf , 0, sizeof(buf));
if ((recvbytes = recv(client_fd, buf, buffer_size, 0)) == -1)
printf("received a message: %s\n", buf);
close(sockfd);
exit(0);
}
客戶端**:
/*client.c*/
#include #include #include #include #include #include #include #include #define port 4321
#define buffer_size 1024
int main(int argc, char *argv)
/*位址解析函式*/
if ((host = gethostbyname(argv[1])) == null)
memset(buf, 0, sizeof(buf));
sprintf(buf, "%s", argv[2]);
/*建立 socket*/
if ((sockfd = socket(af_inet, sock_stream, 0)) == -1)
/*設定 sockaddr_in 結構體中相關引數*/
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);
/*呼叫 connect 函式主動發起對伺服器端的連線*/
if(connect(sockfd,(struct sockaddr *)&serv_addr, sizeof(struct sockaddr))== -1)
/*傳送訊息給伺服器端*/
if ((sendbytes = send(sockfd, buf, strlen(buf), 0)) == -1)
close(sockfd);
exit(0);
}
在執行時需要先啟動伺服器端,再啟動客戶端。
socket程式設計實踐
建立連線 1.1socket 非常類似於open函式,用來開啟乙個網路連線,如果成功則返回乙個網路檔案描述符 int型別 之後我們操作這個網路連線都通過這個網路檔案描述符 1.2bind繫結的意思 好比是ioctl 1.3listen監聽 1.4connect連線 客戶端 傳送和接收 2.1 sen...
五 socket實踐程式設計
1 伺服器端程式編寫 1 socket 2 bind 3 listen 4 accept,返回值是乙個fd,accept正確返回就表示我們已經和前來連線我的客戶端之間建立了乙個tcp連線了,以後我們就要通過這個連線來和客戶端進行讀寫操作,讀寫操作就需要乙個fd,這個fd就由accept來返回了。注意...
socket實踐程式設計1
1 伺服器端程式編寫 1 socket 2 bind 3 listen 4 accept,返回值是乙個fd,accept正確返回就表示我們已經和前來連線我的客戶端之間建立了乙個tcp連線了,以後我們就要通過這個連線來和客戶端進行讀寫操作,讀寫操作就需要乙個fd,這個fd就由accept來返回的了。注...