Linux環境下有專門用於讀寫面向鏈接的套接字函數,分別是send函數和recv函數,send函數和recv函數原型以下:服務器
ssize_t recv(int sockfd, void *buff, size_t nbytes, int flags); socket
頭文件: #include <sys/socket.h> 函數
參數說明:第一個參數sockfd是指定發送端套接字描述符,第二個參數buff存放要發送數據的緩衝區,第三個參數nbytes是實際要發送的數據的字節數,第四個參數flags通常設置爲0。spa
返回值:成功返回發送實際發送的數據的字節數,失敗返回-1.code
ssize_t send(int sockfd, const void *buff, size_t nbytes, int flags); blog
頭文件: #include <sys/socket.h> ci
參數說明:第一個參數sockfd是指定發送端套接字描述符,第二個參數buff存放recv函數接收到數據的緩衝區,第三個參數nbytes是指明buff的長度,第四個參數flags通常設置爲0。字符串
返回值:recv函數返回值有3種狀況原型
大於0,表示成功接收數據,返回值是實際接收的字節數;string
等於0,表示無可用數據或者通訊端已經結束了發送數據;
等於-1,表示接收數據出錯。
如今要用send和recv函數來寫一個面向鏈接數據傳輸的服務器端程序,流程圖以下:
服務器端的執行流程
服務器端的執行流程B
程序代碼以下所示:
#include <stdio.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <strings.h> #include <ctype.h> #include <sys/socket.h> #include <arpa/inet.h> #define MAX_LINE 100 int main(void) { struct sockaddr_in sin; struct sockaddr_in cin; int l_fd; int c_fd; socklen_t len; char buf[MAX_LINE]; char addr_p[INET_ADDRSTRLEN]; int port = 8000; int n; bzero(&sin, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; sin.sin_port = htons(port); /*創立套接字,使用TCP協議*/ if((l_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("fail to creat socket"); exit(1); } /*將地址和套節字綁定*/ if(bind(l_fd, (struct sockaddr *) &sin, sizeof(sin)) == -1) { perror("fail to bind"); exit(1); } /*開始監聽鏈接請求*/ if(listen(l_fd, 10) == -1) { perror("fail to listren"); exit(1); } printf("waiting...\n"); while(1) { /*接受鏈接請求,今後函數中返回後就能夠開始通訊了*/ if((c_fd = accept(l_fd, (struct sockaddr *) &cin, &len)) == -1) { perror("fail to accept"); exit(1); } /*調用recv函數讀取客戶端傳來的信息,不設置任何特殊的標誌*/ n = recv(c_fd, buf, MAX_LINE, 0); if(n = -1) { perror("fail to receive"); exit(1); } else if(n == 0) { printf("the connect has been closed\n "); close(c_fd); continue; } /*將客戶端地址轉換爲字符串*/ inet_ntop(AF_INET, &cin.sin_addr, addr_p, sizeof(addr_p)); printf("client IP is %s, port is %s \n", addr_p, ntohs(cin.sin_port)); printf("connect is : %s\n", buf); n = strlen(buf); sprintf(buf, "%d", n); /*使用send函數將轉換後的字符串發送給客戶端,不設置任何特殊的標誌*/ n = send(c_fd, buf, strlen(buf) + 1, 0); if(n == -1) { perror("fail to send"); exit(1); } if(cloes(c_fd) == -1) { perror("fail to close"); exit(1); } } return 0; }