客户端和服务器刷新缓冲区

时间:2016-04-14 00:07:41

标签: c sockets tcp server client

我为简单的客户端/服务器编写了代码。该代码在运行时执行以下操作。

首先,服务器等待来自客户端的消息,然后要求用户输入要发送给客户端的消息。当客户端首次开始运行时,它会要求用户输入要发送到服务器的消息,然后等待服务器的回复。

当我将第一封邮件从客户端发送到服务器时,程序正常工作,它出现,然后服务器要求我写一条消息发送给客户端,问题就在这里开始:

我键入消息并按Enter键将消息发送到客户端,然后服务器收到相同的先前消息并提示我输入客户端消息。从服务器或客户端发送的消息不会被立即读取和打印,除非我在服务器中键入另一条消息,然后它显示从客户端发送的上一条消息。

服务器代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>

static void bail( const char* on_what ){
fputs(strerror(errno),stderr);
fputs(": ",stderr);
fputs(on_what,stderr);
fputc('\n',stderr);
exit(1);
}

int main(int argc, char** argv) {

int sockfd, bindfd, listenfd, acceptfd, writefd, readfd, len_inet;
struct sockaddr_in address_server, address_client;
char *server_address = "192.168.1.10";
char *server_portno = "9100";
char readBuffer[256], writeBuffer[256];

memset(&address_server, 0, sizeof address_server);
address_server.sin_family = AF_INET;
address_server.sin_port = htons(atoi(server_portno));
address_server.sin_addr.s_addr = inet_addr(server_address);
if(address_server.sin_addr.s_addr == INADDR_NONE)
    bail("bad address");

sockfd = socket(AF_INET, SOCK_STREAM, 0);
if( sockfd == -1 )
    bail("socket()");
printf("socket created\n");

bindfd = bind(sockfd, (struct sockaddr *)&address_server, sizeof address_server);
if( bindfd == -1 )
    bail("bind()");
printf("bind done\n");

listenfd = listen(sockfd, 10);
if( listenfd == -1 )
    bail("listen()");
printf("Listening to Client\n");

len_inet = sizeof address_client;

acceptfd = accept(sockfd, (struct sockaddr *)&address_client, &len_inet);
if( acceptfd == -1 )
    bail("accept()");
    printf("Connection accepted\n");

while(1){

    printf("Reading from Client...\n");
    readfd = read(acceptfd, &readBuffer, sizeof readBuffer-1);
    if( readfd == -1 )
        bail("read()");

    printf("Message from Client: %s\n", readBuffer);

    printf("Enter a message to send to Client:\n");
    fgets(writeBuffer, 255, stdin);
    writefd = write(acceptfd, writeBuffer, sizeof writeBuffer);
    if( writefd == -1 )
        bail("write()");
}

close(acceptfd);
printf("Closing Connection\n");

return (EXIT_SUCCESS);
}

客户代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>

void static bail( const char* on_what ){
fputs(strerror(errno),stderr);
    fputs(": ",stderr);
    fputs(on_what,stderr);
    fputc('\n',stderr);
    exit(1);
}

int main(int argc, char** argv){

int sockfd, connectfd, readfd, writefd, len_inet;
struct sockaddr_in address_server;
char *server_address = "192.168.1.240";
char *server_portno = "9100";
char readBuffer[256], writeBuffer[256];

memset(&address_server, 0, sizeof address_server);
address_server.sin_family = AF_INET;
address_server.sin_port = htons(atoi(server_portno));
address_server.sin_addr.s_addr = inet_addr(server_address);
if( address_server.sin_addr.s_addr == INADDR_NONE)
    bail("bad address");

sockfd = socket(AF_INET, SOCK_STREAM, 0);
if( sockfd == -1 )
    bail("socket()");
printf("socket created\n");

len_inet = sizeof address_server;

connectfd = connect(sockfd, (struct sockaddr *)&address_server, len_inet);
if( connectfd == -1 )
    bail("connect()");
printf("Connected\n");

while(1){
    printf("Please enter a message to send to the Server: \n");
    fgets(writeBuffer, 255, stdin);
    writefd = write(sockfd, writeBuffer, sizeof writeBuffer);
    if( writefd == -1 )
        bail("write(2)");

    printf("Waiting for a message from the server\n");
    readfd = read(sockfd, &readBuffer, sizeof readBuffer-1);
    if( readfd == -1 )
        bail("read(2)");
    readBuffer[readfd] = 0;
    printf("Message from the server: %s\n", readBuffer);
}

close(sockfd);
printf("Connection Closed\n");

return 0;
}

1 个答案:

答案 0 :(得分:2)

您的代码中有几个问题,在服务器中:

printf("Reading from Client...\n");
readfd = read(acceptfd, &readBuffer, sizeof readBuffer-1);
if( readfd == -1 )
    bail("read()");

readBuffer是一个数组,如果传递给一个函数,它已经是一个指向它的第一个元素的指针,所以你不能使用&amp; readBuffer,只需使用readBuffer,然后在读取后,你需要终止缓冲区,就像C中的字符串一样只是空终止的char数组:

printf("Reading from Client...\n");
readfd = read(acceptfd, readBuffer, sizeof readBuffer-1);
if( readfd == -1 )
    bail("read()");
readBuffer[readfd] = '\0';

fgets不会让你知道它读入缓冲区有多少个字符,所以你不能只是整个缓冲区到套接字,而是写字符串,用strlen来确定你需要写的字符串的大小: / p>

writefd = write(acceptfd, writeBuffer, strlen(writeBuffer));

在客户端,缓冲区存在同样的问题:

writefd = write(sockfd, writeBuffer, strlen(writeBuffer));
...
readfd = read(sockfd, readBuffer, sizeof readBuffer-1);
readBuffer[readfd] = '\0';