我有一個基本的服務器客戶端程序,我正在用C編寫,而且我遇到了有關字符串和串聯的問題。 基本上我有一些字符串(下面僅2的例子中),我必須投入其大小由下式確定的緩衝區:保持目標長度的字符串連接
total # of registered people * 33
各字符串中的示例具有的長度比小得多緩衝區的長度。我想拼接後獲得這樣的事情:
[0] [32]
people_list=Mark Amy\0;
其中馬克(其中第二個被插入)就在緩衝區(PEOPLE_LIST)的開始和艾米是32個字符距馬克的開始(我希望我已經說清楚了)。
這是因爲客戶端代碼給了我,我無法修改它。客戶端代碼獲取緩衝區並讀取第一個元素,然後跳轉到32個字符並再次讀取。 我從客戶端的printf的得到的輸出是這樣的:
connected to server
Registered people:
Mark
,而我想這一點:
connected to server
Registered people:
Mark
Amy
的通信是通過套接字,這點我已經檢查落實,但如果你希望提出一些改變,我將不勝感激。
Server代碼:
#include <stdio.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#define LENGTH 32
struct person {
char name[LENGTH+1];
struct person *next;
struct person *prev;
};
struct person *p_head = NULL;
void addPerson(char* name_p){
struct person *new = (struct person*) malloc(sizeof(struct person));
strcpy(new->name, name_p);
new->name[LENGTH]='\0';
new->next=p_head;
new->prev=NULL;
p_head=new;
}
int main(){
int fd_ser;
int fd_c;
int N=100;
char buf[N];
int times=0;
char* path="tmp/sock";
struct sockaddr_un sa;
unlink(path);
sa.sun_family=AF_UNIX;
strncpy(sa.sun_path,(char*) path, sizeof(sa.sun_path));
if((fd_ser=socket(AF_UNIX,SOCK_STREAM,0))<0){ //socket
perror((const char*) (size_t) errno);
exit(EXIT_FAILURE);
}
if (bind(fd_ser,(struct sockaddr *)&sa, sizeof(sa))<0){
perror("bind\n");
}
listen(fd_ser,10); //listen
struct sockaddr_un addr;
int addr_size= sizeof(struct sockaddr_un);
fd_c=0;
while((fd_c=accept(fd_ser,(struct sockaddr*) &addr, (socklen_t*)&addr_size))<0){
printf("waiting for connections...\n");
sleep(2);
}
//initialize list of people
char* Amy="Amy";
char* Mark="Mark";
addPerson(Amy);
addPerson(Mark);
//now concat the name strings in a buffer to be sent to the client
char* people_list;
unsigned int list_len;
int value;
struct person* ptr=(struct person*) malloc(sizeof(struct person));
ptr=p_head;
int offset=0;
int i=0;
while(ptr!=NULL){
i++;
people_list=realloc(people_list,i*LENGTH); //every single name has to be LENGTH characters
strcpy(&people_list[offset],ptr->name);
ptr=ptr->next;
offset=offset+LENGTH;
}
people_list[i*LENGTH]='\0';
list_len=(i*LENGTH)+1;
value=write(fd_c, &(list_len), sizeof(unsigned int));
if(value==-1){
perror("write length");
return -1;
}
int toWrite=list_len;
char *toRead=people_list;
while(toWrite>0){
value=write(fd_c, toRead, toWrite);
if(value==-1){
perror("write data");
return -1;
}
toWrite=toWrite-value;
toRead=toRead+value;
if(toRead<=people_list + list_len) break;
}
close(fd_c);
close(fd_ser);
return 0;
}
客戶端代碼:
#include <stdio.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <assert.h>
#include <errno.h>
#define MAX_LENGTH 2048
#define LENGTH 32
int main(){
int fd_cli;
char* path="tmp/sock";
struct sockaddr_un sa;
sa.sun_family=AF_UNIX;
strncpy(sa.sun_path,(char*) path, sizeof(sa.sun_path));
if((fd_cli = socket(AF_UNIX, SOCK_STREAM, 0))==-1){
perror((const char*) (size_t) errno);
return -1;
}
while((connect(fd_cli,(struct sockaddr*)&sa, sizeof(struct sockaddr_un))) == -1) {
if (errno == ENOENT) { sleep(1); }
else perror("connect:");
errno=0;
sleep(1);
}
printf("connected to server\n");
int value;
unsigned int len_data;
value=read(fd_cli,&(len_data),sizeof(unsigned int));
if(value==-1){
perror("read length");
return -1;
}
char* buffer=malloc(len_data*sizeof(char));
int toRead=len_data;
char *toWrite=buffer;
while(toRead>0){
value=read(fd_cli, toWrite, toRead);
if(value==-1){
perror("read buffer");
return -1;
}
toRead=toRead-value;
toWrite=toWrite+value;
if(toWrite<=buffer + len_data) break;
}
int people_n = len_data/(LENGTH+1);
assert(people_n > 0); //proceeds only if there is at least one person registered
printf("Registered people:\n");
for(int i=0,p=0;i<people_n; ++i, p+=(LENGTH+1)) {
printf(" %s\n", &buffer[p]);
}
close(fd_cli);
return 0;
}
我真的希望我已經清楚地說明了問題!感謝您的幫助!
您可能需要再次仔細閱讀客戶端代碼,特別是'LENGTH'的處理。 – EOF
'struct person * ptr =(struct person *)malloc(sizeof(struct person)); ptr = p_head; '你在這裏泄漏記憶。 – wildplasser
@EOF對!我並沒有考慮客戶端跳過LENGTH + 1個字符,而我沒有考慮在服務器上,現在我修復了它。我多麼失明!謝謝你的提示。 – BattiestFawn66