[英]C socket programming, server send buffer seems not to be cleared
我是socket編程的新手,我遇到了麻煩。 我想實現一個服務器,根據某個客戶端請求回答。 在我的情況下,GET,HEAD或其他錯誤。 考慮以下代碼
如果我在調用send()
之前打印答案(參見下面的服務器端代碼),則消息是正確的。 但是,假設我發送給客戶的是
,從客戶端打印的答案是
You want GET
You want HEAD
You want GETD
HTTP/1.1 400 Bad Request
You want GET Bad Request
因此,似乎從服務器發送的消息有點“覆蓋”,但這怎么可以避免呢? 是否可以“清除服務器緩沖區”,如果這是問題呢?
這是完整的服務器端代碼
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#define BUFSIZE 1024
#define MAXPENDING 100
int main(){
char get[] = "GET";
char head[] = "HEAD";
int serverSocket = socket(PF_INET, SOCK_STREAM, 0);
struct sockaddr_in serverAddress;
serverAddress.sin_family = AF_INET;
serverAddress.sin_port = htons(8080);
serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
memset(&serverAddress.sin_zero, '\0', 8);
bind(serverSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress));
listen(serverSocket, MAXPENDING);
for(;;){
struct sockaddr_in clientAddress;
int clientAddressLength = sizeof(clientAddress);
int clientSocket;
clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddress, &clientAddressLength);
char buf[BUFSIZE];
int bytesRec;
bytesRec = recv(clientSocket, buf, BUFSIZE, 0);
while(bytesRec > 0){
char *result;
result = strtok(buf, " ");
printf("result %s\n", result);
if(strcmp(&buf, &get) == 0){
char answer[] = "You want GET";
send(clientSocket, answer, strlen(answer), 0);
}else{
if(strcmp(&buf, &head) == 0){
char answer[] = "You want HEAD";
send(clientSocket, answer, strlen(answer), 0);
}else{
char answer[] = "HTTP/1.1 400 Bad Request";
send(clientSocket, answer, strlen(answer), 0);
}
}
bytesRec = recv(clientSocket, buf, BUFSIZE, 0);
}
return 0;
}
和客戶端
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
int main(){
int clientSocket = socket(PF_INET, SOCK_STREAM, 0);
struct sockaddr_in clientAddress;
clientAddress.sin_family = AF_INET;
clientAddress.sin_port = 0;
clientAddress.sin_addr.s_addr = htonl(INADDR_ANY);
memset(&clientAddress.sin_zero, '\0', 8/*sizeof(clientAddress.sin_zero)*/);
bind(clientSocket, (struct sockaddr*)&clientAddress, sizeof(clientAddress));
struct sockaddr_in serverAddress;
serverAddress.sin_family = AF_INET;
serverAddress.sin_port = htons(8080);
serverAddress.sin_addr.s_addr = inet_addr("127.0.0.1");
memset(&serverAddress.sin_zero, '\0', 8);
if(connect(clientSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) == -1){
printf("error in connecting!\n");
return 0;
}
char* serverReply[1024];
for(;;){
char request[100];
printf("Enter your request: ");
scanf("%s", &request);
send(clientSocket, request, strlen(msg), 0);
if(recv(clientSocket, serverReply, strlen(serverReply), 0) < 0){
printf("failure in receiving from server!\n");
}else{
printf("%s\n", serverReply);
}
}
close(clientSocket);
return 0;
}
send(clientSocket, request, strlen(msg), 0);
這僅發送字符串字符,不包括終止NULL。 接收緩沖區不會終止服務器端收到的字符串。
這就是您仍然可以看到上一條消息中的“D”字符的原因。
You want GETD <-- 'D' is from the previous 'HEAD'
在服務器上終止接收到的字符串,
buf[bytesRec] = '\0';
編輯:正如@Zan所指出的,不要這樣做:
或從客戶端發送NULL終止符。
send(clientSocket, request, strlen(msg) + 1, 0);
你的strcmp()
如果錯了
(1)而不是buf,您需要將result
與我可以從您的問題中了解的result
進行比較,例如:(您在注釋中說,結果打印為GET)
if(strcmp(result, get) == 0){
(2) @phihag回答應該是
if(strcmp(buf, get) == 0){
^ ^remove &
你在每個strcmp()上都有類似的錯誤,因為buf
, get
, head
都是包機數組。
(3) recv()
不會終止讀取緩沖區,因此在使用它之前最好添加null( \\0
)( 因為我可以注意到您使用buff作為字符串 )
喜歡:
bytesRec = recv(clientSocket, buf, BUFSIZE, 0);
buf[bytesRec] = '\0'
感染你應該只讀取BUFSIZE-1
個字節,一個用於null '\\0'
符號,如:
ytesRec = recv(clientSocket, buf, BUFSIZE-1, 0);
buf[bytesRec] = '\0'
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.