我正在学习posix标准中的C.我正在尝试创建客户端 - 服务器应用程序,现在我尝试处理它们之间的通信。
我不知道如何让客户知道他什么时候应该向服务器发送内容。我想出的很简单 - 当服务器发送消息“1”时,它意味着它现在等待客户端的输入。
我首先尝试使用telnet,但它在某种程度上有效。当我创建客户端应用程序时出现问题 - 它工作在ONCE。后来它决定停止工作。服务器正确地从客户端获取一个输入(当他选择“AddObject”选项时),然后它停止工作(客户端不知道服务器等待消息)。
我试图尽可能地清理我的代码(我的实际代码是一个巨大的,因为我经常尝试不同的东西,并有很多评论),但它可能很糟糕 - 对不起。
服务器
#define _GNU_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/syscall.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <stdbool.h>
#include <poll.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <limits.h>
#include <ctype.h>
#define maxnamel 50
#define BUFLEN 512
#define ERR(source) (fprintf(stderr,"%s:%d\n",__FILE__,__LINE__),\
perror(source),kill(0,SIGKILL),\
exit(EXIT_FAILURE))
struct arg_struct {
int fd;
int org;
};
void usage(void);
int make_socket(uint16_t port);
void usage(void){
fprintf(stderr, "Usage: ./all\n");
exit(EXIT_FAILURE);
}
void sendAndPrint(char* wiadomosc, int sock){
write((int)sock , wiadomosc , strlen(wiadomosc));
printf("%s",wiadomosc);
}
int make_socket(uint16_t port) {
struct sockaddr_in name;
int sock, t=1;
sock = socket(PF_INET,SOCK_STREAM,0);
if (sock < 0) ERR("socket");
name.sin_family = AF_INET;
name.sin_port = htons(port);
name.sin_addr.s_addr = htonl(INADDR_ANY);
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &t, sizeof(t))) ERR("setsockopt");
if (bind(sock,(struct sockaddr*) &name, sizeof(name)) < 0) ERR("bind");
return sock;
}
void addObject (int sock)
{
int read_size, read_size_sum;
char* buf;
char *record;
record=malloc(sizeof(char)*100+1);
buf=malloc(sizeof(char)*10+1);
sendAndPrint("AddObject.\n", sock);
sendAndPrint("Add details of new object.\n", sock);
sendAndPrint("Name:\n", sock);
sleep(0.5);
sendAndPrint("1", sock);
read_size = recv(sock, buf, maxnamel, 0);
printf("%s", buf);
read_size-=1;
buf[read_size]=0;
read_size_sum = read_size;
strcpy(record,buf);
record[read_size-1]=0;
sendAndPrint("Age:\n", sock);
sendAndPrint("1\n", sock);
read_size = recv(sock, buf, 10, 0);
read_size-=1;
buf[read_size+1]=0;
read_size_sum +=read_size;
strcat(record,"-");
strcat(record,buf);
record[read_size_sum-2]=0;
sendAndPrint("Weight:\n", sock);
sendAndPrint("1", sock);
read_size = recv(sock, buf, 10, 0);
buf[read_size-1]=0;
read_size_sum +=read_size;
strcat(record,"-");
strcat(record,buf);
record[read_size_sum-3]=0;
sendAndPrint("Number:\n", sock);
sendAndPrint("1", sock);
read_size = recv(sock, buf, 10, 0);
buf[read_size-1]=0;
read_size_sum +=read_size;
strcat(record,"-");
strcat(record,buf);
record[read_size_sum-3]=0;
strcat(record,"-0");
strcat(record,"\n");
}
void *connection_handler(void *sock_desc)
{
return 0;
}
void *organizer_handler(void *sock_desc)
{
int wybor, read_size;
char client_message[1000];
int sock = *(int*)sock_desc;
sendAndPrint("Start.\n",sock);
sendAndPrint("Choose your action:\n\n1 - Add Object\n2 - To Do\n3 - To Do\n",sock);
sendAndPrint("4 - To Do\n\n\n", sock);
sendAndPrint("1", sock);
while((read_size = recv(sock , client_message , 100 , 0)) > 0 )
{
wybor=atoi(client_message);
if((wybor==1))
addObject(sock);
else
{
sendAndPrint("Wrong choice.\n\n",sock);
sleep(3);
}
sendAndPrint("Choose your action:\n\n1 - Add Object\n2 - To Do\n3 - To Do\n",sock);
sendAndPrint("4 - To Do\n\n\n", sock);
}
return 0;
}
void *doClient(void *arguments){
struct arg_struct *args = arguments;
int fd = args -> fd;
int org = args -> org;
int backlog=10;
int l, c,client_sock, *new_sock;
fd_set set;
pthread_t sniffer_thread2;
struct sockaddr_in client;
l=listen(fd, backlog);
c = sizeof(struct sockaddr_in);
puts("Thread created.");
while(1)
{
FD_ZERO(&set);
FD_SET (fd, &set);
puts("Waiting for connection...");
while((client_sock = accept(fd, (struct sockaddr *)&client, (socklen_t*)&c)))
{
new_sock = malloc(1);
*new_sock = client_sock;
if (org == 1)
{
puts("Organizer has connected. Creating thread...");
if( pthread_create( &sniffer_thread2 , NULL , organizer_handler , (void*) new_sock) < 0)
{
perror("Could not create thread for organizer.");
return 0;
}
} else
{
puts("Normal client has connected. Creating thread...");
if( pthread_create( &sniffer_thread2 , NULL , connection_handler , (void*) new_sock) < 0)
{
perror("Could not create thread for normal client.");
return 0;
}
}
}
}
return 0;
}
void doServer(int fd){
pthread_t sniffer_thread;
char message[1000];
struct arg_struct orgArgs;
orgArgs.fd = fd;
orgArgs.org = 1;
puts("Started server.");
puts("Creating a thread for organizer client...");
if( pthread_create( &sniffer_thread , NULL , doClient , (void *)&orgArgs) < 0)
{
perror("Could not create thread for doClient for organizers.");
return;
}
puts("Type 1 if you want to stop server.");
while (scanf("%s", message))
{
if(atoi(message) == 1)
{
puts("Closing server.");
break;
}
else
puts("Type 1 if you want to stop server.");
}
}
int main(int argc, char** argv) {
int fd;
uint16_t port=8089;
if(argc != 1){
usage();
}
fd = make_socket(port);
doServer(fd);
return EXIT_SUCCESS;
}
客户端
#define _GNU_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/syscall.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <stdbool.h>
#include <poll.h>
#include <netdb.h>
#define HERR(source) (fprintf(stderr,"%s(%d) at %s:%d\n",source,h_errno,__FILE__,__LINE__),\
exit(EXIT_FAILURE))
#define BUFLEN 512
#define ERR(source) (fprintf(stderr,"%s:%d\n",__FILE__,__LINE__),\
perror(source),kill(0,SIGKILL),\
exit(EXIT_FAILURE))
int fd;
int make_socket(void){
int sock;
sock = socket(PF_INET,SOCK_STREAM,0);
if(sock < 0) ERR("socket");
return sock;
}
struct sockaddr_in make_address(uint16_t port){
struct sockaddr_in addr;
struct hostent *hostinfo;
addr.sin_family = AF_INET;
addr.sin_port = htons (port);
hostinfo = gethostbyname("localhost");
if(hostinfo == NULL)HERR("gethostbyname");
addr.sin_addr = *(struct in_addr*) hostinfo->h_addr;
return addr;
}
int connect_socket(uint16_t port){
struct sockaddr_in addr;
int socketfd;
socketfd = make_socket();
addr=make_address(port);
if(connect(socketfd,(struct sockaddr*) &addr,sizeof(struct sockaddr_in)) < 0){
if(errno!=EINTR) ERR("connect");
else {
fd_set wfds;
int status;
socklen_t size = sizeof(int);
FD_ZERO(&wfds);
FD_SET(socketfd, &wfds);
if(TEMP_FAILURE_RETRY(select(socketfd+1,NULL,&wfds,NULL,NULL))<0) ERR("select");
if(getsockopt(socketfd,SOL_SOCKET,SO_ERROR,&status,&size)<0) ERR("getsockopt");
if(0!=status) ERR("connect");
}
}
return socketfd;
}
void doClientORG(int fd){
int read_size;
int msg_size;
char client_message[1000];
char message[1000];
puts("Waiting for server.");
while((read_size = recv(fd , client_message , 100 , 0)) > 0 )
{
client_message[read_size]=0;
if(atoi(client_message) == 1)
{
puts("Inside");
scanf("%s", message);
/*printf("Message: %s\n\n", message);*/
write(fd, message,1);
}
else
printf("%s", client_message);
}
}
int main(int argc, char** argv) {
int fd;
uint16_t port=8089;
char* message;
fd=connect_socket(port);
doClientORG(fd);
return EXIT_SUCCESS;
}
有什么想法吗?我做错了什么,或者我的想法开头是不正确的?