?? tcpserver.c
字號:
/* tcpServer.c */
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h> /* close */
#define SUCCESS 0
#define ERROR 1
#define END_LINE 0x0A
#define SERVER_PORT 1500
#define MAX_MSG 100
/* 定義函數 readline */
int read_line();
int main (int argc, char *argv[]) {
int sd, newSd, cliLen;
struct sockaddr_in cliAddr, servAddr; /* 套接字地址結構體 */
char line[MAX_MSG];
/* 建立套接字 */
sd = socket(AF_INET, SOCK_STREAM, 0);
if(sd<0) {
perror("cannot open socket ");
return ERROR;
}
/* 設定套接字地址結構體servAddr中的參數
綁定服務器端口號 */
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
servAddr.sin_port = htons(SERVER_PORT);
if(bind(sd, (struct sockaddr *) &servAddr, sizeof(servAddr))<0) {
perror("cannot bind port ");
return ERROR;
}
listen(sd,5);
/* 這里仍然是一個死循環,服務器端
等待客戶端發來的連接請求 */
while(1) {
printf("%s: waiting for data on port TCP %u\n",argv[0],SERVER_PORT);
cliLen = sizeof(cliAddr);
newSd = accept(sd, (struct sockaddr *) &cliAddr, &cliLen);
if(newSd<0) {
perror("cannot accept connection ");
return ERROR;
}
/* 初始化line緩沖區,地址為0x0,長度為MAX_MSG */
memset(line,0x0,MAX_MSG);
/* 調用read_line函數來接收數據 */
while(read_line(newSd,line)!=ERROR) {
printf("%s: received from %s:TCP%d : %s\n", argv[0],
inet_ntoa(cliAddr.sin_addr),
ntohs(cliAddr.sin_port), line);
/* 初始化line緩沖區 */
memset(line,0x0,MAX_MSG);
} /* end of while(read_line) */
} /* end of while (1) */
}
/* 下面這個程序僅僅是測試使用,在某種程度上說并不健全。*/
/* 當必要時數據從套接字緩沖區中讀取,但不是按照字節順序
一個字節一個字節的讀取。所有被接收到的數據都被讀取到緩
沖區中。可以設置END_CHAR作為數據行的結束符。read_line
函數調用成功則返回其讀取的字節數,這些數據由指針line_to_return
指向。 */
int read_line(int newSd, char *line_to_return) {
static int rcv_ptr=0;
static char rcv_msg[MAX_MSG];
static int n;
int offset;
offset=0;
while(1) {
if(rcv_ptr==0) {
/* 從套接字緩沖區中讀取 */
memset(rcv_msg,0x0,MAX_MSG); /* 初始化緩沖區 */
n = recv(newSd, rcv_msg, MAX_MSG, 0); /* 等待、讀取數據 */
if (n<0) {
perror(" cannot receive data ");
return ERROR;
} else if (n==0) {
printf(" connection closed by client\n");
close(newSd);
return ERROR;
}
}
/* 如果已經從套接字讀取到了數據 */
/* 或者 */
/*緩沖區中還有其他數據 */
/* 把指針line_to_return指向該緩沖區的數據 */
while(*(rcv_msg+rcv_ptr)!=END_LINE && rcv_ptr<n) {
memcpy(line_to_return+offset,rcv_msg+rcv_ptr,1);
offset++;
rcv_ptr++;
}
/* end of line + end of buffer => return line */
if(rcv_ptr==n-1) {
/* 將最后一個字節設置為END_LINE */
*(line_to_return+offset)=END_LINE;
rcv_ptr=0;
return ++offset;
}
/* 盡管已經到了讀取數據的末尾,
但是緩沖區中還有其他數據,
這時做如下處理: */
if(rcv_ptr <n-1) {
/* 設置最后一個字節為 END_LINE */
*(line_to_return+offset)=END_LINE;
rcv_ptr++;
return ++offset;
}
/* 或者是已經到了緩沖區的末尾,但是緩沖區太小,裝不下需要
接收的數據,這時等待套接字上新的數據到達 */
if(rcv_ptr == n) {
rcv_ptr = 0;
}
} /* end of while */
}/* end of main */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -