我为简单的客户端/服务器编写了代码。该代码在运行时执行以下操作。
首先,服务器等待来自客户端的消息,然后要求用户输入要发送给客户端的消息。当客户端首次开始运行时,它会要求用户输入要发送到服务器的消息,然后等待服务器的回复。
当我将第一封邮件从客户端发送到服务器时,程序正常工作,它出现,然后服务器要求我写一条消息发送给客户端,问题就在这里开始:
我键入消息并按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;
}
答案 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';