服务端循环accept,如果每次客户端只发送一次请求,就没问题,
但是如果客户端循环发送数据,服务端就接收不到一次连接中的第二次请求。
下面贴代码,求解这个问题到底咋回事
服务端 sock_serv.c
#include
#include
#include
#include
#include
#include
#include
#include
#define BACKLOG 10
#define RECVBUF_SIZE 4096
#define PORT 20000
int init_server(int type){
int sockfd;
if ((sockfd = socket(AF_INET, type, 0)) == -1){
printf("create socker error\n");
return -1;
}
struct sockaddr_in addrv4;
bzero(&addrv4, sizeof(addrv4));
addrv4.sin_family = AF_INET;
addrv4.sin_port = htons(PORT);
addrv4.sin_addr.s_addr = INADDR_ANY;
if (bind(sockfd, (struct sockaddr *)&addrv4, sizeof(addrv4)) < 0){
printf ("bind sockfd error\n");
return -1;
}
if (listen(sockfd, BACKLOG) < 0){
printf ("listen sockfd error\n");
return -1;
}
return sockfd;
}
int main(void){
int sockfd, newfd;
if ((sockfd = init_server(SOCK_STREAM)) == -1){
printf ("server init failed\n");
exit(1);
}
while (1) {
struct sockaddr client_addr;
bzero(&client_addr, sizeof(client_addr));
socklen_t len = sizeof(client_addr);
char recvbuf[RECVBUF_SIZE];
if ((newfd = accept(sockfd, &client_addr, &len)) < 0){
printf("%s\n", strerror(errno));
printf ("accept request error\n");
exit(1);
}
printf(" the client fd is :%d\n", newfd);
printf ("client ip is %s", inet_ntoa(((struct sockaddr_in *)&client_addr)->sin_addr));
ssize_t ret;
if ((ret = recv(newfd, recvbuf, RECVBUF_SIZE, 0)) < 0){
printf("%s\n", strerror(errno));
printf("recv data error \n");
exit(1);
}
if (ret == 0) {
printf("always read to EOF\n");
}
printf("the client request data is :\n\t\t%s", recvbuf);
char *resp_data = "the server was recvived success!";
if (send(newfd, resp_data, strlen(resp_data), 0) == -1){
printf("response data error\n");
exit(1);
}
//shutdown(newfd, SHUT_RDWR);
//close(newfd);
if (strcmp(recvbuf, "exit") == 0){
shutdown(sockfd, SHUT_RDWR);
close(sockfd);
}
}
}
客户端 sock_client.c
#include
#include
#include
#include
#include
#include
#include
#define BUFSIZE 4096
#define PORT 20000
void error(const char *str){
printf("%s\n"
"the error info is : %s\n", str, strerror(errno));
}
int init_client(){
int sockfd;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
error("socket error");
return -1;
}
struct sockaddr_in addrv4;
bzero(&addrv4, sizeof(addrv4));
addrv4.sin_family = AF_INET;
addrv4.sin_port = htons(PORT);
addrv4.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect(sockfd, (struct sockaddr *)&addrv4, (socklen_t) sizeof(addrv4)) == -1){
error("connect error");
return -1;
}
return sockfd;
}
int main(void){
char consolebuf[BUFSIZE];
char recvbuf[BUFSIZE];
int sockfd, len, recvlen;
if ((sockfd = init_client()) == -1){
error("init client error");
exit(1);
}
while (1){
printf("input >>");
if ((len = read(STDIN_FILENO, &consolebuf, BUFSIZE)) == -1){
error("read data error");
exit(1);
}
if (strcmp(consolebuf, "exit-client") == 0){
break;
}
if (send(sockfd, consolebuf, len, 0) == -1){
error("send data error");
exit(1);
}
if ((recvlen = recv(sockfd, recvbuf, BUFSIZE, 0)) == -1){
error("receive the server response error\n");
exit(1);
}
write(STDOUT_FILENO, recvbuf, recvlen);
}
shutdown(sockfd, SHUT_RDWR);
close(sockfd);
exit(0);
}
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。