C 使用线程或fork的文本聊天应用程序
我面临一个问题,我正在制作一个文本聊天程序。我将同时在两个不同的终端上运行相同的程序。我在程序中使用的文件位于一个终端,我将写入数据,它将存储在文件中,下一个终端将读取并显示它,反之亦然 我写了两个函数send和receive现在我想我的send和receive将在同一时间工作,也就是当我在发送消息的同时我可以接收消息。我应该怎么做我已经尝试过分叉,但我想我不知道怎么使用它。我应该如何管理它,因为同一个文件由两个进程访问,每个进程访问两次任何建议或帮助谢谢 这是到目前为止我的密码C 使用线程或fork的文本聊天应用程序,c,file-io,fork,C,File Io,Fork,我面临一个问题,我正在制作一个文本聊天程序。我将同时在两个不同的终端上运行相同的程序。我在程序中使用的文件位于一个终端,我将写入数据,它将存储在文件中,下一个终端将读取并显示它,反之亦然 我写了两个函数send和receive现在我想我的send和receive将在同一时间工作,也就是当我在发送消息的同时我可以接收消息。我应该怎么做我已经尝试过分叉,但我想我不知道怎么使用它。我应该如何管理它,因为同一个文件由两个进程访问,每个进程访问两次任何建议或帮助谢谢 这是到目前为止我的密码 #includ
#include<stdio.h>
#include <sys/stat.h>
#include<unistd.h>
void send()
{
char message[256];
fgets(message , 256 , stdin);
//printf("Message is : %s" , message);
FILE * f1;
f1= fopen("chatfile.txt", "w");
if(f1== NULL)
{
printf("not open ");
}
fprintf(f1 , "%s" , message);
fclose(f1);
}
//-------------------------------------------------------
void recieve()
{
char message[256];
FILE * f1;
f1= fopen("chatfile.txt", "r");
fgets(message , 256 , f1);
printf("Message is : %s" , message);
fclose(f1);
}
//-------------------------------------------------------
int file_size()
{
struct stat st;
stat("chatfile.txt" , &st);
int size = st.st_size;
return size;
}
//------------------------------------------------------
int main()
{
int size =0;
//printf("%d" , getpid());
pid_t pid;
pid = fork();
while(1)
{
if( pid == 0)
{
printf("parent");
send();
}
else
{
printf("child");
recieve();
}
}
}
#包括
#包括
#包括
作废发送()
{
字符消息[256];
fgets(信息,256,标准输入);
//printf(“消息为:%s”,消息);
文件*f1;
f1=fopen(“chatfile.txt”,“w”);
如果(f1==NULL)
{
printf(“未打开”);
}
fprintf(f1,“%s”,消息);
fclose(f1);
}
//-------------------------------------------------------
无效接收()
{
字符消息[256];
文件*f1;
f1=fopen(“chatfile.txt”、“r”);
fgets(信息,256,f1);
printf(“消息为:%s”,消息);
fclose(f1);
}
//-------------------------------------------------------
int file_size()
{
结构统计;
stat(“chatfile.txt”和&st);
int size=st.st\u size;
返回大小;
}
//------------------------------------------------------
int main()
{
int size=0;
//printf(“%d”,getpid());
pid_t pid;
pid=fork();
而(1)
{
如果(pid==0)
{
printf(“母公司”);
send();
}
其他的
{
printf(“儿童”);
receive();
}
}
}
这里的问题是同步。您不知道发送何时完成,接收者可能会读取部分结果,或者根本不读取任何结果。您要么需要一种机制,如信号量,要么使用另一种媒介,如命名管道。您还应该考虑到您的关机问题,senario
下面是一个简单的命名管道示例,我尽可能多地保留了您的代码:
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <stdlib.h>
/* Easier to alter if defined in one place
safere to put named-pipes in /tmp */
#define PIPENAME "/tmp/chatfile.pipe"
/* An empty parameter list means no parameter
checking, not no parameters! */
void send(void)
{
char message[256];
fgets(message , 256 , stdin);
FILE * f1;
f1= fopen(PIPENAME, "w");
if(f1 == NULL) {
/* printf writes to stdout
perror writes to stderr, and includes the error */
perror("not open ");
exit(1);
}
fprintf(f1 , "%s" , message);
fclose(f1);
}
//-------------------------------------------------------
void recieve(void)
{
char message[256];
FILE * f1;
f1= fopen(PIPENAME, "r");
/* You should check EVERY open */
if (f1 == NULL) {
perror("not open ");
exit(1);
}
fgets(message , 256 , f1);
printf("Message is : %s" , message);
fclose(f1);
}
//------------------------------------------------------
int main(int argc, char *argv[])
{
int iResult = mkfifo(PIPENAME,0666);
if (iResult == -1 && errno != EEXIST) {
perror("Unable to create pipe");
exit(1);
}
pid_t pid;
pid = fork();
while(1)
{
if( pid == 0) {
printf("parent");
send();
}
else {
printf("child");
recieve();
}
}
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
/*如果在一个地方定义,则更容易修改
安全地将命名管道放入/tmp*/
#定义PIPENAME“/tmp/chatfile.pipe”
/*空参数列表表示没有参数
检查,不是没有参数*/
作废发送(作废)
{
字符消息[256];
fgets(信息,256,标准输入);
文件*f1;
f1=fopen(管道名称,“w”);
如果(f1==NULL){
/*printf写入标准输出
perror写入stderr,并包含错误*/
perror(“非公开”);
出口(1);
}
fprintf(f1,“%s”,消息);
fclose(f1);
}
//-------------------------------------------------------
无效接收(无效)
{
字符消息[256];
文件*f1;
f1=fopen(管道名称,“r”);
/*你应该检查每一个开口*/
如果(f1==NULL){
perror(“非公开”);
出口(1);
}
fgets(信息,256,f1);
printf(“消息为:%s”,消息);
fclose(f1);
}
//------------------------------------------------------
int main(int argc,char*argv[])
{
int-iResult=mkfifo(管道名称,0666);
如果(iResult==-1&&errno!=EEXIST){
perror(“无法创建管道”);
出口(1);
}
pid_t pid;
pid=fork();
而(1)
{
如果(pid==0){
printf(“母公司”);
send();
}
否则{
printf(“儿童”);
receive();
}
}
返回0;
}
我还应该补充一点,对于命名管道,无需再次关闭和打开它(尽管原子写入的字节数有限制)。我很乐意提供帮助,但您所在的位置和需要所在的位置之间的差距很大。您需要:1)发送和接收之间的同步2)检测文件创建的方法3)多个文件名4)接收在显示文件后删除文件5)围绕发送/接收的循环构造6)分离每个终端文件位置的方法7)。。。