基于socket的客户端与服务端聊天程序,当使用子进程时可完成,把fork()更改为进程之后,只能实现一对一通信,可以检测到多客户端接入,但是返回信息都只能发回到第一个接入的客户端。
//server.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <pthread.h>
pthread_mutex_t mutex[3];
struct handlerBuf
{
int fd;
int serial;
};
void *writeHandler(void *hb)
{
struct handlerBuf *hb_w = (struct handlerBuf *)hb;
char sndbuf[128];
char rev[128];
sprintf(rev,"get connect,you'r NO.%d\n",hb_w->serial+1);
write(hb_w->fd,rev,128);
while(1){
getchar();
pthread_mutex_lock(&mutex[hb_w->serial]);
memset(sndbuf,0,128);
printf(">");
scanf("%s",sndbuf);
write(hb_w->fd,sndbuf,sizeof(sndbuf));
printf("seng over\n");
pthread_mutex_unlock(&mutex[hb_w->serial]);
getchar();
}
}
void *readHandler(void *hb)
{
int n_read;
struct handlerBuf *hb_r = (struct handlerBuf *)hb;
char readbuf[128];
while(1){
n_read = read(hb_r->fd,readbuf,128);
pthread_mutex_lock(&mutex[hb_r->serial]);
if(n_read > 0)
{
printf("get from NO.%d:%s\n",hb_r->serial+1,readbuf);
}
pthread_mutex_unlock(&mutex[hb_r->serial]);
}
}
void *clientHandler(void *hb)
{
pthread_t newthread;
pthread_create(&newthread,NULL,readHandler,hb);
writeHandler(hb);
}
int main(int argc,char **argv)
{
int s_fd;
int c_fd;
int n_read;
pthread_t thread[3];
int i = 0;
int j = 0;
char readbuf[128];
char msg[128];
struct handlerBuf hb[3];
struct sockaddr_in s_addr;
struct sockaddr_in c_addr;
memset(&s_addr,0,sizeof(struct sockaddr_in));
memset(&c_addr,0,sizeof(struct sockaddr_in));
if(argc != 3)
{
printf("ip addr failed\n");
}
s_fd = socket(AF_INET,SOCK_STREAM,0);
if(s_fd == -1)
{
perror("socket");
exit(-1);
}
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(atoi(argv[2]));
inet_aton(argv[1],&s_addr.sin_addr);
bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));
listen(s_fd,3);
int clen = sizeof(struct sockaddr_in);
while(1)
{
c_fd = accept(s_fd,(struct sockaddr *)&c_addr,&clen);
if(c_fd == -1)
{
perror("accept");
}else{
printf("NO.%d client connect\n",j+1);
pthread_mutex_init(&mutex[j],NULL);
hb[j].fd = c_fd;
hb[j].serial = j;
pthread_create(&thread[j],NULL,clientHandler,(void **)&hb);
j++;
if(j == 3)
{
j = 0;
}
}
}
return 0;
}
//client.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
pthread_mutex_t mutex;
void *writeHandler(void *fd)
{
int w_fd = *(int *)fd;
char sndbuf[128];
while(1)
{
getchar();
memset(sndbuf,0,128);
pthread_mutex_lock(&mutex);
printf(">");
scanf("%s",sndbuf);
write(w_fd,sndbuf,sizeof(sndbuf));
printf("seng over---\n");
pthread_mutex_unlock(&mutex);
getchar();
}
}
void *readHandler(void *fd)
{
int n_read;
int r_fd = *(int *)fd;
char readbuf[128];
while(1)
{
memset(readbuf,0,128);
n_read = read(r_fd,readbuf,128);
pthread_mutex_lock(&mutex);
if(n_read > 0)
{
printf("---get:%s\n",readbuf);
}
pthread_mutex_unlock(&mutex);
}
}
int main(int argc,char **argv)
{
int c_fd;
int n_read;
pid_t pid;
char readbuf[128];
char msgn[128];
struct sockaddr_in c_addr;
pthread_mutex_init(&mutex,NULL);
memset(&c_addr,0,sizeof(struct sockaddr_in));
c_fd = socket(AF_INET,SOCK_STREAM,0);
if(c_fd == -1)
{
perror("socket");
exit(-1);
}
c_addr.sin_family = AF_INET;
c_addr.sin_port = htons(atoi(argv[2]));
inet_aton(argv[1],&c_addr.sin_addr);
connect(c_fd,(struct sockaddr *)&c_addr,sizeof(struct sockaddr));
pthread_t newthread;
pthread_create(&newthread,NULL,readHandler,(void *)&c_fd);
writeHandler((void *)&c_fd);
while(1);
return 0;
}
运行结果及报错内容
编译无报错,运行后发现服务器无法与多客户端通信
我的解答思路和尝试过的方法
没有解题思路
我想要达到的结果
客户端发送消息服务器可以接收到,并且返回客户端序号在客户端显示