C套接字编程,服务器发送缓冲区似乎没有被清除
我对socket编程非常陌生,我对它有困难。我想实现一个服务器,它根据特定的客户端请求进行应答。在我的例子中,要么是GET,HEAD,要么是一个错误。考虑下面的代码 如果在调用C套接字编程,服务器发送缓冲区似乎没有被清除,c,sockets,C,Sockets,我对socket编程非常陌生,我对它有困难。我想实现一个服务器,它根据特定的客户端请求进行应答。在我的例子中,要么是GET,HEAD,要么是一个错误。考虑下面的代码 如果在调用send()(请参阅下面的服务器端代码)之前打印答案,则消息是正确的。但我想说的是我的客户 得到 头 得到 试验 得到 ,从客户端打印的答案是 You want GET You want HEAD You want GETD HTTP/1.1 400 Bad Request You want GET Bad Request
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;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义bufsize1024
#定义MAXPENDING 100
int main(){
char get[]=“get”;
字符头[]=“头”;
int serverSocket=socket(PF_INET,SOCK_STREAM,0);
serverAddress中的结构sockaddr_;
serverAddress.sin_family=AF_INET;
serverAddress.sin_port=htons(8080);
serverAddress.sin\u addr.s\u addr=htonl(INADDR\u ANY);
memset(&serverAddress.sin_zero,'\0',8);
绑定(serverSocket,(struct sockaddr*)&serverAddress,sizeof(serverAddress));
侦听(serverSocket,MAXPENDING);
对于(;;){
clientAddress中的结构sockaddr_;
int clientAddress length=sizeof(clientAddress);
int客户端套接字;
clientSocket=accept(serverSocket,(struct sockaddr*)&clientAddress,&clientAddress长度);
字符buf[BUFSIZE];
int bytesRec;
bytesRec=recv(clientSocket,buf,BUFSIZE,0);
while(bytesRec>0){
字符*结果;
结果=strtok(buf,“”);
printf(“结果%s\n”,结果);
if(strcmp(&buf,&get)==0){
char-answer[]=“您想要得到”;
发送(客户端套接字,应答,strlen(应答),0);
}否则{
如果(strcmp(&buf,&head)==0){
char-answer[]=“您想要头部”;
发送(客户端套接字,应答,strlen(应答),0);
}否则{
char-answer[]=“HTTP/1.1 400错误请求”;
发送(客户端套接字,应答,strlen(应答),0);
}
}
bytesRec=recv(clientSocket,buf,BUFSIZE,0);
}
返回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;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int main(){
int clientSocket=socket(PF_INET,SOCK_STREAM,0);
clientAddress中的结构sockaddr_;
clientAddress.sin_family=AF_INET;
clientAddress.sin_端口=0;
clientAddress.sin\u addr.s\u addr=htonl(INADDR\u ANY);
memset(&clientAddress.sin_zero,“\0',8/*sizeof(clientAddress.sin_zero)*/);
绑定(clientSocket,(struct sockaddr*)&clientAddress,sizeof(clientAddress));
serverAddress中的结构sockaddr_;
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(“连接错误!\n”);
返回0;
}
char*serverReply[1024];
对于(;;){
字符请求[100];
printf(“输入您的请求:”);
scanf(“%s”,请求(&R));
发送(clientSocket,请求,strlen(msg),0);
if(recv(clientSocket,serverReply,strlen(serverReply),0)<0){
printf(“从服务器接收失败!\n”);
}否则{
printf(“%s\n”,serverReply);
}
}
关闭(clientSocket);
返回0;
}
如果您的strcmp()
错误
(1)您需要与结果进行比较,而不是像我从您的问题中所理解的那样进行比较,比如:(您在评论中说结果打印为GET)
(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'
infect您应该只读BUFSIZE-1
字节,为空'\0'
符号保留一个字节,如:
ytesRec = recv(clientSocket, buf, BUFSIZE-1, 0);
buf[bytesRec] = '\0'
这只发送字符串,不包括终止NULL。接收缓冲区不在服务器端终止接收的字符串
这就是为什么您仍然看到上一条消息中的“D”字符
You want GETD <-- 'D' is from the previous 'HEAD'
编辑:正如@Zan指出的,不要这样做:
或者从客户端发送空终止符
send(clientSocket, request, strlen(msg) + 1, 0);
您可以删除问题中的重复代码并发布一些客户端代码吗?printf(“结果%s\n”,result);
在服务器端打印什么?对不起,我再次测试了它,假设我发送了“GET aa bb”,它会打印“result GET”,“result aa”,result“bb”。这显然是一个进一步的问题,但即使只发送“得到”或“头”"结果在上述行为中,您是否发送了一个c样式的字符串,即以null结尾?您是否确实发送了null字符?即使您发送了,您似乎也没有遵循任何类型的协议来检查null是否已被实际接收-如果您发送了4个字符,“bytesRec”可能会返回为1、2、3或4。-您必须循环untl空值出现在缓冲区的某个地方,然后解析您的消息直到该空值。strcmp问题真的很重要吗?第二个问题是否会衰减为指针?@jsn您的意思是隐式typecase字可以在strcmp()中将char(*)[]
转换为char*
那么是的,你是对的。@jsn我认为strcmp问题很重要。它
You want GETD <-- 'D' is from the previous 'HEAD'
buf[bytesRec] = '\0';
send(clientSocket, request, strlen(msg) + 1, 0);