我有一个可以处理多个客户端的服务器代码。客户端程序可以连接到服务器并发出Unix命令,例如ls,date,clear等。我有两个我无法弄清的问题。 1)当我最初输入ls作为参数时,它将返回一些奇怪的垃圾,然后如果我再次输入ls,它将开始正常工作。因此,仅在一开始,它就会给我带来垃圾。 2)当我在终端上输入参数'ps -ael'时,它将正常工作,但是之后我收到一条'Failed'消息,该消息来自客户端代码,特别是在while(1)循环中if (send(clientSocket, s, echolen, 0) != echolen)
,这是发生错误的地方。我很想知道是否有人可以指出问题所在,我认为这可能是因为我创建的char数组太大了,但我不确定。
客户:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 4444
#define BUFFSIZE 2048
int main(int argc, char *argv[]){
int clientSocket, ret, portnum;
struct sockaddr_in serverAddr;
int received = 0;
unsigned int echolen;
char buffer[1024];
if(argc < 3){
fprintf(stderr,"usage %s <server-ip-addr> <server-port>\n", argv[0]);
exit(0);
}
portnum = atoi(argv[2]);
clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if(clientSocket < 0){
printf("Error in connection.\n");
exit(1);
}
printf("Client Socket is created.\n");
memset(&serverAddr, '\0', sizeof(serverAddr));
// memset(&buffer, '\0', sizeof(buffer));
// serverAddr.sin_family = AF_INET;
// serverAddr.sin_port = htons(PORT);
// serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
// bzero((char *) &serverAddr, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
if(!inet_aton(argv[1], &serverAddr.sin_addr)){
fprintf(stderr, "Error invalid server IP address\n");
exit(1);
}
serverAddr.sin_port = htons(portnum);
ret = connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(ret < 0){
printf("Error in connection.\n");
exit(1);
}
printf("Connected to server.\n");
char s[100];
while(1){
fgets(s, 100, stdin);
s[strlen(s)-1]='\0';
echolen = strlen(s);
/* send() from client; */
if (send(clientSocket, s, echolen, 0) != echolen)
{
printf("Failed");
}
if(strcmp(s,"exit") == 0) // check if exit is typed
exit(0);
fprintf(stdout, "Message from server: ");
while (received < echolen)
{
int bytes = 0;
/* recv() from server; */
if ((bytes = recv(clientSocket, buffer, echolen, 0)) < 1)
{
printf("Failed to get Information");
}
received += bytes;
buffer[bytes] = '\0';
fprintf(stdout, buffer);
}
int bytes = 0;
do {
buffer[bytes] = '\0';
printf("%s\n", buffer);
} while((bytes = recv(clientSocket, buffer, BUFFSIZE-1, 0))>=BUFFSIZE-1);
buffer[bytes] = '\0';
printf("%s\n", buffer);
printf("\n");
}
}
服务器:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 4444
#define BUFFSIZE 2048
#define MAX 2048
void setup(char inputBuffer[], char *args[], int *background){
const char s[4] = " \t\n";
char *token;
token = strtok(inputBuffer, s);
int i = 0;
while(token != NULL){
args[i] = token;
i++;
token = strtok(NULL, s);
}
args[i] = NULL;
}
void HandleClient(int sock){
char buffer[BUFFSIZE];
int received = -1;
char data[MAX];
memset(data, 0, MAX);
while(1){
data[0] = '\0';
if((received = recv(sock, buffer, BUFFSIZE, 0)) < 0){
printf("Error");
}
buffer[received] = '\0';
strcat(data, buffer);
if(strcmp(data, "exit") == 0){
exit(0);
}
puts(data);
char *args[100];
setup(data, args, 0);
int pipefd[2], length;
if(pipe(pipefd)){
printf("failed to create pipe");
}
pid_t pid = fork();
char path[MAX];
if(pid==0)
{
close(pipefd[0]); // close the readonly side of the pipe
//close(1); // close the original stdout
dup2(pipefd[1],1); // duplicate pipfd[1] to stdout
dup2(pipefd[1], fileno(stderr));
//close(pipefd[0]); // close the readonly side of the pipe
close(pipefd[1]); // close the original write side of the pipe
printf("before execvp");
execvp(args[0],args); // finally execute the command
// exit(0);
}
else
if(pid>0)
{
close(pipefd[1]);
memset(path,'\0',MAX);
while(length=read(pipefd[0],path,MAX-1)){
//printf("Data read so far %s\n", path);
if(send(sock,path,strlen(path),0) != strlen(path) ){
printf("Failed");
}
fflush(NULL);
//printf("Data sent so far %s\n", path);
memset(path,0,MAX);
}
close(pipefd[0]);
//exit(1); removed so server will not terminate
}
else
{
printf("Error !\n");
exit(0);//
}
}
}
int main(){
int sockfd, ret;
struct sockaddr_in serverAddr;
int newSocket;
struct sockaddr_in newAddr;
socklen_t addr_size;
char buffer[1024];
pid_t childpid;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0){
printf("Error in connection.\n");
exit(1);
}
printf("Server Socket is created.\n");
memset(&serverAddr, '\0', sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(PORT);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
ret = bind(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(ret < 0){
printf("Error in binding");
exit(1);
}
printf("Bind to port %d\n", 4444);
if(listen(sockfd, 10) == 0){
printf("Listening....\n");
}else{
printf("Error in binding.\n");
}
while(1){
newSocket = accept(sockfd, (struct sockaddr*) &newAddr, &addr_size);
if(newSocket < 0){
exit(1);
}
printf("Connection accepted from %s:%d\n", inet_ntoa(newAddr.sin_addr), ntohs(newAddr.sin_port));
//worker
if((childpid = fork()) == 0){
close(sockfd);
while(1){
recv(newSocket, buffer, 1024, 0);
if(strcmp(buffer, ":exit") == 0){
printf("Disconnected from %s:%d\n", inet_ntoa(newAddr.sin_addr), ntohs(newAddr.sin_port));
break;
}else{
printf("Client: %s\n", buffer);
send(newSocket, buffer, strlen(buffer), 0);
bzero(buffer, sizeof(buffer));
}
HandleClient(newSocket);
}
}
}
close(newSocket);
return 0;
}