我的问题陈述是使用客户端服务器程序创建,更新,删除,显示记录。 这是客户端的我的代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>
/* BufferLength is 100 bytes */
#define BufferLength 150
/* Default host name of server system. Change it to your default */
/* server hostname or IP. If the user do not supply the hostname */
/* as an argument, the_server_name_or_IP will be used as default*/
#define SERVER "The_server_name_or_IP"
/* Server's port number */
#define SERVPORT 3111
#define ID_ZERO "ID CAN'T BE ZERO"
#define FILE_ERR "CAN'T OPEN FILE"
#define ID_EXIST "ID ALREADY EXIST"
#define DEL_OK "Deleted Record"
#define CREATED_RECORD "CREATED_RECORD"
#define EMP_NOT_FOUND "EMP NOT FOUND"
#define UPDATED_RECORD "UPDATED RECORD"
#define BufferLength 150
/* Pass in 1 parameter which is either the */
/* address or host name of the server, or */
/* set the server name in the #define SERVER ... */
#pragma pack(1)
struct emprec
{
int empid;
int operation;
char name[200];
};
#pragma pack(0)
typedef struct emprec emp;
char data1[100];
int main(int argc, char *argv[])
{
/* Variable and structure definitions. */
int sd, rc, length = sizeof(int);
struct sockaddr_in serveraddr;
char buffer[BufferLength];
char server[255];
char temp;
int count=0;
int totalcnt = 0;
emp temp1;
struct hostent *hostp;
unsigned char* datas = (unsigned char*)malloc(sizeof(temp1));
/* The socket() function returns a socket */
/* descriptor representing an endpoint. */
/* The statement also identifies that the */
/* INET (Internet Protocol) address family */
/* with the TCP transport (SOCK_STREAM) */
/* will be used for this socket. */
/******************************************/
/* get a socket descriptor */
if((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("Client-socket() error");
exit(-1);
}
else
printf("Client-socket() OK\n");
/*If the server hostname is supplied*/
if(argc > 1)
{
/*Use the supplied argument*/
strcpy(server, argv[1]);
printf("Connecting to the following %s, port %d ...\n", server, SERVPORT);
}
else
/*Use the default server name or IP*/
strcpy(server, SERVER);
memset(&serveraddr, 0x00, sizeof(struct sockaddr_in));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(SERVPORT);
if((serveraddr.sin_addr.s_addr = inet_addr(server)) == (unsigned long)INADDR_NONE)
{
/* When passing the host name of the server as a */
/* parameter to this program, use the gethostbyname() */
/* function to retrieve the address of the host server. */
/***************************************************/
/* get host address */
hostp = gethostbyname(server);
if(hostp == (struct hostent *)NULL)
{
printf("HOST NOT FOUND --> ");
/* h_errno is usually defined */
/* in netdb.h */
printf("h_errno = %d\n",h_errno);
printf("---This is a client program---\n");
printf("Command usage: %s <server name or IP>\n", argv[0]);
close(sd);
exit(-1);
}
memcpy(&serveraddr.sin_addr, hostp->h_addr, sizeof(serveraddr.sin_addr));
}
/* After the socket descriptor is received, the */
/* connect() function is used to establish a */
/* connection to the server. */
/***********************************************/
/* connect() to server. */
if((rc = connect(sd, (struct sockaddr *)&serveraddr, sizeof(serveraddr))) < 0)
{
perror("Client-connect() error");
close(sd);
exit(-1);
}
else
printf("Connection established...\n");
/* Send string to the server using */
/* the write() function. */
/*********************************************/
/* Write() some string to the server. */
while(1)
{
printf("Enter the choice\n");
printf("1- Insert a new record into file\n");
printf("2- Update the record\n");
printf("3- Display the records\n");
printf("4- Delete the record\n");
printf("5- Close the connection with the server\n");
int choice;
scanf("%d",&choice);
switch(choice){
case 1:
//emp temp1;
temp1.operation=1;
printf("Enter the id of the record\n");
scanf("%d",&temp1.empid);
if(temp1.empid==0)
{
printf("id cannot be zero\n");
break;
}
printf("Enter name correspond to that id\n");
scanf("%s",temp1.name);
if(strlen(temp1.name)==0)
{
printf("name cannot be empty\n");
break;
}
//printf("id that is being sent is %d\n",temp1.empid);
//printf("Name sent is %s\n",temp1.name);
memset(datas,0,sizeof(temp1));
memcpy(datas,&temp1,sizeof(temp1));
rc =write(sd,datas,sizeof(temp1));
if(rc < 0)
{
perror("Client-write() error");
rc = getsockopt(sd, SOL_SOCKET, SO_ERROR, &temp, &length);
if(rc == 0)
{
//Print out the asynchronously received error.
errno = temp;
perror("SO_ERROR was");
}
close(sd);
exit(-1);
}
else
{
printf("Client-write() is OK\n");
printf("String successfully sent!\n");
printf("Waiting the %s to echo back...\n", server);
}
// }//else loop
totalcnt = 0;
// while(totalcnt < BufferLength)
// {
/* Wait for the server to echo the */
/* string by using the read() function. */
/***************************************/
/* Read data from the server. */
rc = read(sd, &buffer, 100);
if(rc < 0)
{
perror("Client-read() error");
close(sd);
exit(-1);
}
else if (rc == 0)
{
printf("Server program has issued a close()\n");
close(sd);
exit(-1);
}
else
totalcnt += rc;
// }
printf("Client-read() is OK\n");
printf("Echoed data from the following server: %s\n", buffer);
if(strcmp(buffer,CREATED_RECORD)==0){
count++;
printf("count incremented\n");
}
break;
//}//while loop
case 2: //Update the record
{
//emp temp21;
temp1.operation=2;
printf("Enter the id for which the record is to update \n");
scanf("%d",&temp1.empid);
printf("Enter name correspond to that id\n");
scanf("%s",temp1.name);
printf("id that is being sent t update is %d\n",temp1.empid);
memset(datas,0,sizeof(temp1));
memcpy(datas,&temp1,sizeof(temp1));
rc =write(sd,datas,sizeof(temp1));
if(rc < 0)
{
perror("Client-write() error");
rc = getsockopt(sd, SOL_SOCKET, SO_ERROR, &temp, &length);
if(rc == 0)
{
//Print out the asynchronously received error.
errno = temp;
perror("SO_ERROR was");
}
close(sd);
exit(-1);
}
else
{
printf("Client-write() is OK\n");
printf("String successfully sent!\n");
printf("Waiting the %s to echo back...\n", server);
}
// }//else loop
totalcnt = 0;
//while(totalcnt < BufferLength)
//{
/* Wait for the server to echo the */
/* string by using the read() function. */
/***************************************/
/* Read data from the server. */
rc = read(sd, &buffer, 25);
if(rc < 0)
{
perror("Client-read() error");
close(sd);
exit(-1);
}
else if (rc == 0)
{
printf("Server program has issued a close()\n");
close(sd);
exit(-1);
}
else
totalcnt += rc;
//}
printf("Client-read() is OK\n");
printf("Echoed data from the following server: %s\n", buffer);
break;
case 3: //display
{
//emp temp31;
printf("IN DISPLAY\n");
printf("value of count is %d\n",count);
temp1.operation=3;
memset(datas,0,sizeof(temp1));
memcpy(datas,&temp1,sizeof(temp1));
rc =write(sd,datas,sizeof(temp1));
if(rc < 0)
{
perror("Client-write() error");
rc = getsockopt(sd, SOL_SOCKET, SO_ERROR, &temp, &length);
if(rc == 0)
{
//Print out the asynchronously received error.
errno = temp;
perror("SO_ERROR was");
}
close(sd);
exit(-1);
}
else
{
printf("Client-write() is OK\n");
printf("String successfully sent!\n");
// printf("Waiting the %s to echo back...\n", server);
}
//emp temmp;
int ii =1;
while(ii<=count){
printf("value of count is %d\n",count);
rc= read(sd,&buffer,100);
memcpy(&temp1,buffer,sizeof(temp1));
printf("\nid is = %d name is = %s\n",temp1.empid,temp1.name);
ii++;
printf("value of ii is %d\n",ii);
}
printf("display loop ended\n");
//ii=0;
/*if(rc < 0)
{
perror("Server-read() error");
close(sd);
exit (-1);
}
else if(rc == 0)
{
printf("Client program has issued a close()\n");
close(sd);
exit(-1);
}
else
{
totalcnt += rc;
printf("Server-read() is OK\n");
}*/
//}
break;
}
break;
case 4:
{
emp temp41;
temp1.operation=4;
printf("Enter id to be deleted \n");
scanf("%d",&temp1.empid);
printf("enter to be deleted is %d\n",temp1.empid);
memset(datas,0,sizeof(temp1));
memcpy(datas,&temp1,sizeof(temp1));
//sleep(10);
printf("sending\n");
rc =write(sd,datas,sizeof(temp1));
printf("sent\n");
if(rc < 0)
{
perror("Client-write() error");
rc = getsockopt(sd, SOL_SOCKET, SO_ERROR, &temp, &length);
if(rc == 0)
{
//Print out the asynchronously received error.
errno = temp;
perror("SO_ERROR was");
}
close(sd);
exit(-1);
}
else
{
printf("Client-write() is OK\n");
printf("String successfully sent!\n");
printf("Waiting the %s to echo back...\n", server);
count--;
}
rc= read(sd,&buffer,100);
//FILE_ERR
printf("Message from server is %s\n",buffer);
if(strcmp(buffer,FILE_ERR)==0){
printf("Server cant open the file.... please check at the server end\n");
close(sd);
exit(0);
//count++;
//printf("count incremented\n");
}
// if(
break;
}
case 5: // Shutdown case
{
//emp temp51;
temp1.operation=5;
memset(datas,0,sizeof(temp1));
memcpy(datas,&temp1,sizeof(temp1));
//sleep(10);
printf("Closing client and asked server too to close\n");
rc =write(sd,datas,sizeof(temp1));
if(rc < 0)
{
perror("Client-write() error");
rc = getsockopt(sd, SOL_SOCKET, SO_ERROR, &temp, &length);
if(rc == 0)
{
//Print out the asynchronously received error.
errno = temp;
perror("SO_ERROR was");
}
close(sd);
exit(-1);
}
else
{
//printf("Client-write() is OK\n");
//printf("String successfully sent!\n");
//printf("Waiting the %s to echo back...\n", server);
}
close(sd);
exit(0);
break;
}
}//switch bracket
}//switch
}//while 1
}//main
这是服务器的我的代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <unistd.h>
/* BufferLength is 100 bytes */
/* Server port number */
//ALL CONSTANTS
#define SERVPORT 3111
#define ID_ZERO "ID CAN'T BE ZERO"
#define FILE_ERR "CAN'T OPEN FILE"
#define ID_EXIST "ID ALREADY EXIST"
#define DEL_OK "Deleted Record"
#define CREATED_RECORD "CREATED_RECORD"
#define EMP_NOT_FOUND "EMP NOT FOUND"
#define UPDATED_RECORD "UPDATED RECORD"
#define BufferLength 150
#pragma pack(1)
struct emprec
{
int empid;
int operation;
char name[20];
};
#pragma pack(0)
typedef struct emprec emp;
int main()
{
/* Variable and structure definitions. */
int sd, sd2, rc, length = sizeof(int);
int totalcnt = 0, on = 1,count=0;
int i=1;//use only one int
int flag1=0;//use only one flag
char temp;
char buffer[BufferLength];
char sbuf[25];
struct sockaddr_in serveraddr;
struct sockaddr_in their_addr;
FILE *fd=NULL,*fd1=NULL;
fd_set read_fd;
emp temp2,temp8,temp3;
unsigned char* sdata = (unsigned char*)malloc(sizeof(temp2));
/* The socket() function returns a socket descriptor */
/* representing an endpoint. The statement also */
/* identifies that the INET (Internet Protocol) */
/* address family with the TCP transport (SOCK_STREAM) */
/* will be used for this socket. */
/************************************************/
/* Get a socket descriptor */
if((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("Server-socket() error");
/* Just exit */
exit (-1);
}
else
printf("Server-socket() is OK\n");
/* The setsockopt() function is used to allow */
/* the local address to be reused when the server */
/* is restarted before the required wait time */
/* expires. */
/***********************************************/
/* Allow socket descriptor to be reusable */
if((rc = setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on))) < 0)
{
perror("Server-setsockopt() error");
close(sd);
exit (-1);
}
else
printf("Server-setsockopt() is OK\n");
/* bind to an address */
memset(&serveraddr, 0x00, sizeof(struct sockaddr_in));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(SERVPORT);
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
/* connect to any client that used port 3005. */
if((rc = bind(sd, (struct sockaddr *)&serveraddr, sizeof(serveraddr))) < 0)
{
perror("Server-bind() error");
/* Close the socket descriptor */
close(sd);
/* and just exit */
exit(-1);
}
else
printf("Server-bind() is OK\n");
/* The listen() function allows the server to accept */
/* incoming client connections. In this example, */
/* the backlog is set to 10. This means that the */
/* system can queue up to 10 connection requests before */
/* the system starts rejecting incoming requests.*/
/*************************************************/
/* Up to 10 clients can be queued */
if((rc = listen(sd, 10)) < 0)
{
perror("Server-listen() error");
close(sd);
exit (-1);
}
else
printf("Server-Ready for client connection...\n");
/* The server will accept a connection request */
/* with this accept() function, provided the */
/* connection request does the following: */
/* - Is part of the same address family */
/* - Uses streams sockets (TCP) */
/* - Attempts to connect to the specified port */
/***********************************************/
/* accept() the incoming connection request. */
int sin_size = sizeof(struct sockaddr_in);
if((sd2 = accept(sd, (struct sockaddr *)&their_addr, &sin_size)) < 0)
{
perror("Server-accept() error");
close(sd);
exit (-1);
}
else
printf("Server-accept() is OK\n");
/*client IP*/
printf("Server-new socket, sd2 is OK...\n");
//printf("Got connection from the f***ing client: %s\n", inet_ntoa(their_addr.sin_addr));
while(1){
/* The select() function allows the process to */
/* wait for an event to occur and to wake up */
/* the process when the event occurs. In this */
/* example, the system notifies the process */
/* only when data is available to read. */
/***********************************************/
/* Wait for up to 15 seconds on */
/* select() for data to be read. */
//FD_ZERO(&read_fd);
//FD_SET(sd2, &read_fd);
//rc = select(sd2+1, &read_fd, NULL, NULL, &timeout);
//if((rc == 1) && (FD_ISSET(sd2, &read_fd)))
//{
/* Read data from the client. */
totalcnt = 0;
//while(totalcnt < BufferLength)
//{
/* When select() indicates that there is data */
/* available, use the read() function to read */
/* 100 bytes of the string that the */
/* client sent. */
/***********************************************/
/* read() from client */
rc= read(sd2,&buffer,100);
if(rc < 0)
{
perror("Server-read() error");
close(sd);
close(sd2);
exit (-1);
}
else if (rc == 0)
{
printf("Client program has issued a close()\n");
close(sd);
close(sd2);
exit(-1);
}
else
{
totalcnt += rc;
printf("Server-read() is OK\n");
}
memcpy(&temp2,buffer,sizeof(temp2));
printf("operation is %d\n",temp2.operation);
// declare it upwards
if (temp2.operation==1)//write record
{
printf("in write record\n");
printf("id is %d\n",temp2.empid);
printf("name is %s\n",temp2.name);
fd = fopen("/home/abc/Desktop/test34.txt","a+");
while(i<=count)
{
printf("value of i is %d and count is %d\n",i,count);
fread(&temp3.empid,sizeof(temp3.empid),1,fd);
fread(&temp3.name,sizeof(temp3.name),1,fd);
if(temp2.empid==temp8.empid)
{
printf("in create:: going in id checking loop\n");
flag1=1;
temp8.empid=0;
i=0;
break;
}
i++;
}
if (flag1==1)
{
memset(sbuf,0,sizeof(sbuf));
strcpy(sbuf,ID_EXIST);
printf("temp2.empname is %s\n",temp2.name);
rc = write(sd2, sbuf, sizeof(sbuf));
i=0;
flag1=0;
//break;
}
else
{
count++;
fwrite(&temp2.empid,sizeof(temp2.empid),1,fd);
fwrite(&temp2.name,20,1,fd);
fclose(fd);
sleep(1);
memset(sbuf,0,sizeof(sbuf));
strcpy(sbuf,CREATED_RECORD);
printf("Server-Echoing back to client...\n");
rc = write(sd2, sbuf, sizeof(sbuf));
if(rc <0)
{
perror("Server-write() error");
/* Get the error number. */
rc = getsockopt(sd2, SOL_SOCKET, SO_ERROR, &temp, &length);
if(rc == 0)
{
/* Print out the asynchronously */
/* received error. */
errno = temp;
perror("SO_ERROR was: ");
}
else
printf("Server-write() is OK\n");
}
}//else bracket
}
if (temp2.operation==2)//update
{
memcpy(&temp2,buffer,sizeof(temp2));
printf("in case update\n");
printf("id is %d\n",temp2.empid);
printf("name is %s\n",temp2.name);
int id,flag=0,i=1;
//emp temp4;
fd = fopen("/home/abc/Desktop/test34.txt","r+");
if(fd==NULL)
{
printf("File cannot be opened\n");
return 1;
}
id = temp2.empid;
printf("id to search is %d\n",id);
i=1;
while(i<=count)
{
fread(&temp8.empid,sizeof(temp8.empid),1,fd);
printf("Debbugging id read is %d\n",temp8.empid);
if(temp2.empid==temp8.empid)
{
int size = ftell(fd);
printf("pointer is at position %d\n",size);
printf("emp id found\n");
fseek(fd,size,SEEK_SET);
printf("data to write is %s\n",temp2.name);
fwrite(&temp2.name,20,1,fd);
memset(sbuf,0,sizeof(sbuf));
strcpy(sbuf,UPDATED_RECORD);
printf("Server-Echoing back to client...\n");
rc = write(sd2, sbuf, sizeof(sbuf));
flag=1;
break;
}
i++;
}//while inside if
if(flag!=1)
{
memset(sbuf,0,sizeof(sbuf));
strcpy(sbuf,EMP_NOT_FOUND);
printf("Server-Echoing back to client...\n");
rc = write(sd2, sbuf, sizeof(sbuf));
printf("No emp found");
flag=0;
}
fclose(fd);
}//if update
if (temp2.operation==3)//display
{
printf("In display\n");
emp temp6;
int i =1;
fd = fopen("/home/abc/Desktop/test34.txt","r+");
if(fd==NULL)
{
printf("File cannot be opened\n");
return 1;
}
while(i<=count)
{
fread(&temp6.empid,sizeof(temp6.empid),1,fd);
fread(&temp6.name,sizeof(temp6.name),1,fd);
printf("\nid is = %d name is = %s\n",temp6.empid,temp6.name);
memset(sdata,0,sizeof(temp6));
memcpy(sdata,&temp6,sizeof(temp6));
printf("temp2.empname is %s\n",temp2.name);
rc = write(sd2, sdata, sizeof(temp6));//add a check here
sleep(1);
i++;
}
fclose(fd);
}//if display
if (temp2.operation==4)//delete record - NOT YET COMPLETE
{
printf("In case 4 THAT IS DELETE \n");
int found =0,i=1;
fd = fopen("/home/abc/Desktop/test34.txt","r+");
if(fd==NULL)
{
printf("File cannot be opened\n");
memset(sbuf,0,sizeof(sbuf));
strcpy(sbuf,FILE_ERR);
printf("sbuf is %s\n",sbuf);
rc = write(sd2, sbuf, sizeof(sbuf));
return 1;
}
fd1 = fopen("/home/abc/Desktop/test335.txt","a+");
if(fd1==NULL)
{
printf("File cannot be opened\n");
memset(sbuf,0,sizeof(sbuf));
strcpy(sbuf,FILE_ERR);
printf("sbuf is %s\n",sbuf);
rc = write(sd2, sbuf, sizeof(sbuf));
return 1;
}
printf("name to search is %s\n",temp2.name);
printf("id to delete is %d\n",temp2.empid);
emp temp7,temp10;
memcpy(&temp10,buffer,sizeof(temp10));
printf("temp 10 id to delete is %d\n",temp10.empid);
while(i<=count){
fread(&temp7.empid,sizeof(temp7.empid),1,fd);
fread(&temp7.name,sizeof(temp7.name),1,fd);
if(temp2.empid==temp7.empid){
printf("A requested by name found and deleted\n");
found = 1;
count--;
}else{
fwrite(&temp7,sizeof(temp7),2,fd1);
}
if(!found)
{
printf("cannot found the record\n");
}
i++;
}
fclose(fd);
fclose(fd1);
remove("/home/abc/Desktop/test34.txt");
rename("/home/abc/Desktop/test335.txt","/home/tarun/Desktop/test34.txt");
memset(sbuf,0,sizeof(sbuf));
strcpy(sbuf,DEL_OK);
rc = write(sd2, sbuf, sizeof(sbuf));
//for debugging
fd = fopen("/home/abc/Desktop/test34.txt","r+");
if(fd==NULL)
{
printf("File cannot be opened\n");
return 1;
}
i=0;
while(i<=count)
{
fread(&temp7.empid,sizeof(temp7.empid),1,fd);
fread(&temp7.name,sizeof(temp7.name),1,fd);
printf("\nid is = %d name is = %s\n",temp7.empid,temp7.name);
i++;
}
}// if delete record
/* When the data has been sent, close() */
/* the socket descriptor that was returned */
/* from the accept() verb and close() the */
/* original socket descriptor. */
/*****************************************/
/* Close the connection to the client and */
/* close the server listening socket. */
/******************************************/
if (temp2.operation==5)//close connection
{
printf("client has asked to shutdown ... Its time to go bbye\n");
close(sd2);
close(sd);
exit(0);
return 0;
}
}
}
我已经尝试过测试所有可能的情况。但是如果您有请求请查看代码并注释可以添加更多检查。 此外我删除后删除记录中的问题我无法得到确切的值请告诉我什么是问题
答案 0 :(得分:1)
发布的代码中存在多个逻辑错误。
以下是此类错误的详细信息:
rc= read(sd,&buffer,100);
memcpy(&temp1,buffer,sizeof(temp1));
printf("\nid is = %d name is = %s\n",temp1.empid,temp1.name);
1) read() does not append a string terminator byte
2) memcpy() is copying the full buffer[] rather than just the number of bytes read
3) printf...%s... does not stop printing until it encounters a '\0' byte.
如果读取的字节数只有几个字节
,会发生什么(这可能发生,并且经常发生,这是使用'select()/ read()'并将套接字设置为非阻塞循环的原因,以确保获得所有必需/所需的输入字节。 )
仅将实际读取字节数'rc'复制到'temp1'结构。 然后插入'\ 0'作为下一个字节。
注意:套接字尚未设置为“非阻塞”,因此代码将“挂起”,直到读取100个字节或套接字超时。