2 qq28970484 qq28970484 于 2016.03.26 23:04 提问

linux c socket tcp客户端只能发送一次,发送第二次服务端接收不到,必须重启才行

服务端循环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);

}


2个回答

devmiao
devmiao   Ds   Rxr 2016.03.26 23:14
已采纳
qq28970484
qq28970484 不好意思,是我自己二了,已经知道是怎么回事了
2 年多之前 回复
qq28970484
qq28970484 就是说,send了一次之后,然后recv,然后循环在send就报错了,这个是为啥能说一下不
2 年多之前 回复
qq28970484
qq28970484 我大概看了一下代码,你这个客户端属于一次性的短链接,我贴的这个程序如果搞成短链接的也是没有问题的,一次connect多次send和recv要怎么做呢?
2 年多之前 回复
bealing
bealing   Rxr 2016.03.26 23:41

服务器端,要为接受连接的socket,专门创见一个线程用于接收和发送信息

qq28970484
qq28970484 嗯,现在开始阶段没用线程,造成这个问题的原因是我忘记循环recv了。。。才导致的不能接收到客户端的第二次发送的。。。
2 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐
socket客户端数据发送的数据服务端接收不到
在项目中,遇到一个socket接口,需要由我们系统封装为webservice,然后向外提供,在封装的过程中,遇到了一个问题: 根据对方提供的地址和端口,我直接通过telnet可以发送数据,但是通过程序却无法发送数据。我首先采用的是下面的程序: http://zhidao.baidu.com/question/388088995.html import java.io.IOExcept
Java写的TCP聊天程序,服务端收不到客户端发送的数据
这个操蛋的问题居然浪费了我好几个小时,记得以前写的时候没出现这种情况的,今天写了一下服务端居然收不到客户端发送的消息,最后终于找到问题所在了,客户端向输出流中写数据时,最后面要加换行符\n,这样服务端才能正常接收数据!!!妈蛋!!!切记!!!
网络编程中服务器发送的消息,客户端收不到也没有反应的几点原因
在使用 PrintWriter  时出现的问题 [java] view plain copy PrintWriter out = new PrintWriter(new BufferedWriter(        new OutputStreamWriter(this.client.getOutputStream(),          "
关于socket flush()目标端接收不到数据,close()可以接收到数据的问题
最近在写一个简单的socket示例时遇到一个问题,使用write.flush()目标端read接收不到数据,调用close()后数据可正常接收。这让我很是费解,记得当初学习flush方法时,都说明这个方法是强制将缓存区内容刷新到输出流中。难道是socket输出流有不一样。看到网上很多人在问这个问题,解释的也是五花八门的。后来我终于找到了原因,有这样疑惑的同胞们可以参考下,出问题的不是输出的逻辑,而是
Node.js UDP服务器无法收到客户端消息
Node.js UDP服务器无法收到客户端消息          在《Node.js开发实战详解》这本书的第四章里,在架设Node.js服务器后,运行客户端程序,服务器无法收到消息。server.jsvar dgram = require('dgram'); var server = dgram.createSocket('udp4'); server.on('listening', funct
Socket服务端客户端以tcp/ip协议发送接收报文
实现了java socket编程基于tcp/ip协议的简单服务端,客户端通信,用于发送报文,接收解析报文。
socket客户端接收信息被堵塞
是不能等于-1撒.. 他在等你那边给他写东西呢.. 你应该在服务器端结束的时候给他写个东西过去..让他知道已经结束了.. 还有什么问题HI我哈  但是read方法本身不就有告知客户端文件传送结束的功能么 当读到文件结束符的时候它会返回-1的啊 确实读文件结束就是-1... 但是你的客户端读的不是文件啊..服务器才是读文件..所以服
TCP连接建立好了之后 服务端一直不接受数据怎么办
TCP连接建立好了之后 服务端一直不接受数据怎么办?参考Tcp服务端一直sleep,客户端发送数据问题
Linux C TCP服务器收不到报文
TCP服务器收不到报文本Markdown编辑器使用[StackEdit][6]修改而来,用它写博客,将会带来全新的体验哦:问题描述 最近写了一个tcp服务器,测试发现始终收不到服务器报文。问题原因 进一步调试发现了问题所在,accept函数如下://if ((client_sock = accept(server_sock, (struct sockaddr *)&addr, &len)) <
java socket 服务器端接受 C socket 客户端消息
/**       * 通信格式转换       *       * Java 和一些windows编程语言如c、c++、delphi所写的网络程序进行通讯时,需要进行相应的转换       * 高、低字节之间的转换       * windows的字节序为低字节开头       * linux,unix的字节序为高字节开头       * java则无论平台变化,都是