C 服务器程序停留在read()函数上,但write()函数在客户端程序中运行良好
我正在使用C语言中的套接字编程方法编写一个简单聊天室程序。我实现了客户端可以连接到服务器并向服务器发送消息,服务器应该向其他服务器分发消息 但是,当我尝试测试我的程序并尝试让两个客户端进行通信时,一些奇怪的事情发生了。如果我遵循以下步骤,就会发生奇怪的事情C 服务器程序停留在read()函数上,但write()函数在客户端程序中运行良好,c,linux,sockets,network-programming,C,Linux,Sockets,Network Programming,我正在使用C语言中的套接字编程方法编写一个简单聊天室程序。我实现了客户端可以连接到服务器并向服务器发送消息,服务器应该向其他服务器分发消息 但是,当我尝试测试我的程序并尝试让两个客户端进行通信时,一些奇怪的事情发生了。如果我遵循以下步骤,就会发生奇怪的事情 运行服务器程序并等待连接 打开一个客户端程序并连接到服务器,然后发送两条消息,两条消息均成功 打开另一个客户端并执行相同操作,第一个客户端可以接收第二个客户端完美发送的消息。 但是,当我切换到第一台服务器时,尝试写入新消息并发送到要分发的服务
/*tcp client.c*/
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
//在终端获得输入时随时向服务器发送消息
作废*发送(作废*插入)
{
字符发送器[80];
//将套接字保存到int指针中
int*SockedCopy=Socked;
while(fgets(发送方,sizeof(发送方),stdin)){
//只要输入字符串,就发送它
int messageSize=strlen(发送方)+1;
写入(*SockedCopy,&messageSize,sizeof(int));
int i=write(*SockedCopy,sender,messageSize);//在发送消息时两者都起作用
printf(“write over!write()返回%d\n”,i);
//检查这是否是退出消息
if(strcmp(发送方,“q!”)==0)
出口(1);
}
}
//从服务器接收消息
无效*接收(无效*插入)
{
int*SockedCopy=Socked;
字符接收器[80];
而(1){
//持续阅读信息
int reveiverEnd=0;
reveiverEnd=读取(*SockedCopy,接收器,1000);
接收器[reveiverEnd]='\0';
FPUT(接收器、标准输出);
接收器[0]='\0';
}
}
int main()
{
int-sockfd,n;
pthread\u t threadSend;
pthread_t threadReceive;
serv、cli中的结构sockaddr_;
char rec[1000];
char-send[80];
//输入用户名
printf(“输入用户名:”);
fgets(发送、sizeof(发送)、标准输入);
send[strlen(send)-1]='\0';
int MessageSize=strlen(发送);
//创建袜子
sockfd=套接字(PF_INET,SOCK_STREAM,0);
//创建服务器信息
bzero(&serv,sizeof(serv));
serv.sin_family=PF_INET;
serv.sin_port=htons(8888);
serv.sin_addr.s_addr=inet_addr(“127.0.0.1”/*本地机器*/);
//连接到服务器
连接(sockfd,(struct sockaddr*)&serv,sizeof(struct sockaddr));
//将用户名发送到服务器
写入(sockfd,&MessageSize,sizeof(int));
写入(sockfd、send、sizeof(send));
//获取成功的连接消息
n=读取(sockfd,rec,1000);//n标记实际长度
rec[n]='\0';
FPUT(记录、标准输出);
发送[0]='\0';
//打开发送线程
pthread_创建(&threadSend、0、Send和&sockfd);
//打开接收消息线程
pthread_创建(&threadReceive、0、Receive和&sockfd);
//合上袜子并合上两条线
对于(int i=0;i<100;++i)
睡眠(10万);
pthread_退出(&threadSend);
pthread_退出(&threadReceive);
关闭(sockfd);
返回0;
}
服务器.C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <sys/socket.h>
#include <linux/in.h>
#include <unistd.h>
#include <unistd.h>
pthread_t thread;
pthread_t threadClient[100];
int ServerSock;
//Every client's information
typedef struct
{
int sock;
char UserName[16];
struct sockaddr address;
int addr_len;
} connection_t;
static connection_t conn[100];
//this function distributes the messsage/status of single client to the other
//Info is the message needed to be distributed
int SendInfo(void* Info)
{
char *info = Info;
for(int i = 0; i < 100; ++i)
//send to the client that exists and doesn't quit room
if(conn[i].addr_len != -1 && conn[i].addr_len != 0){
if(send (conn[i].sock, info , strlen(info) + 1, 0) == -1)
printf("error occured, send to %s fail", conn[i].UserName);
printf("send %s to %s successfully!\n", info, conn[i].UserName);
}
return 0;
}
//This function deals with single client, aim to receive message from this client
//and then send them to another using SendIinfo
void* Receive(void* clientnumber)
{
int* Clientnumber = clientnumber;
while(1)
{
//read the message from the client
char *Buffer;
int messageLen = 0;
read(conn[*Clientnumber].sock, &messageLen, sizeof(int));
printf("receive from %d\n", messageLen);
if(messageLen > 0)
{
Buffer = (char *)malloc((messageLen+1)*sizeof(char));
read(conn[*Clientnumber].sock, Buffer, messageLen); // the program stucks here and don't know why
if(Buffer[0] != ':') continue;
Buffer[messageLen] = '\0';
//whether the client want to quit
if( Buffer[1] == 'q' && Buffer[2] == '!' )
{
//constitute quit message and delete this client
char quit[] = " quit the chat room";
char quitMessage[20];
quitMessage[0] = '\0';
strcat(conn[*Clientnumber].UserName, quit);
SendInfo(quitMessage);
conn[*Clientnumber].addr_len = -1;
pthread_exit(&threadClient[*Clientnumber]);
}
else{
//constitute the message
char begin[] = " says";
char messageDistribute[200];
messageDistribute[0] = '\0';
strcat(messageDistribute, conn[*Clientnumber].UserName);
strcat(messageDistribute, begin);
strcat(messageDistribute, Buffer);
SendInfo(messageDistribute);
}
free(Buffer);
}
else
continue;
}
}
//aim to accept whenever there is a client trying to connect
void * process(void * ptr)
{
pthread_t clientThread[100];
char * buffer;
int len;
//the number of the client connecting now
int clientNumber = 0;
long addr = 0;
while(1){
//waiting to be connected
if(clientNumber < 100)
{
conn[clientNumber].sock = accept(ServerSock, &conn[clientNumber].address, &conn[clientNumber].addr_len);
}
else
break;
//the length of the message
read(conn[clientNumber].sock, &len, sizeof(int));
if (len > 0)
{
//multiple information of a client
addr = (long)((struct sockaddr_in *)&conn[clientNumber].address)->sin_addr.s_addr;
buffer = (char *)malloc((len+1)*sizeof(char));
buffer[len] = 0;
read(conn[clientNumber].sock, buffer, len);
//send success message to the client
send (conn[clientNumber].sock, "You have entered the chatroom, Start CHATTING Now!\n", 51, 0);
//save client's nick name
strcpy(conn[clientNumber].UserName, buffer);
printf("User <%s> has entered the Chatroom!\n", conn[clientNumber].UserName);
printf("There are %d people in Chatroom now!\n",clientNumber+1);
free(buffer);
//create a thread dealing the messages from a single client
int number = clientNumber;
pthread_create(&threadClient[clientNumber], 0, Receive, &number);
}
clientNumber += 1;
}
pthread_exit(0);
}
int main(int argc, char ** argv){
struct sockaddr_in address;
int port = 8888;
connection_t * connection;
//create socked
ServerSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
//bind the socked to a port
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(port);
if (bind(ServerSock, (struct sockaddr *)&address, sizeof(struct sockaddr_in)) < 0)
{
fprintf(stderr, "error: cannot bind socket to port %d\n", port);
return -4;
}
//listen for connections
listen(ServerSock, 100);
printf("the server is ready and listening\n");
//creating a thread dealing with connections
pthread_create(&thread, 0, process, (void *)connection);
//keep this program working
for(int i = 0; i < 100; ++i)
sleep(10000);
//close socked and thread
pthread_detach(thread);
close(ServerSock);
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
pthread\u t线程;
pthread_t threadClient[100];
int-ServerSock;
//每个客户的信息
类型定义结构
{
int袜子;
字符用户名[16];
结构sockaddr地址;
国际地址;
}连接;
静态连接接头[100];
//此功能将单个客户端的消息/状态分发给其他客户端
//信息是需要分发的消息
int SendInfo(无效*信息)
{
char*info=info;
对于(int i=0;i<100;++i)
//发送到已存在且未退出房间的客户端
if(conn[i].addr\u len!=-1&&conn[i].addr\u len!=0){
如果(发送(连接[i].sock,info,strlen(info)+1,0)=-1)
printf(“发生错误,发送到%s失败”,连接[i]。用户名);
printf(“将%s成功发送到%s!\n”,信息,连接[i]。用户名);
}
返回0;
}
//此函数用于处理单个客户端,目的是从该客户端接收消息
//然后使用SendIinfo将它们发送给另一个
作废*接收(作废*客户号)
{
int*Clientnumber=Clientnumber;
而(1)
{
//从客户端读取消息
字符*缓冲区;
int messageLen=0;
读取(conn[*Clientnumber].sock,&messageLen,sizeof(int));
printf(“从%d接收”,messageLen);
如果(messageLen>0)
{
Buffer=(char*)malloc((messageLen+1)*sizeof(char));
read(conn[*Clientnumber].sock、Buffer、messageLen);//程序在此处和
if (len > 0)
{
[...]
int number = clientNumber;
pthread_create(&threadClient[clientNumber], 0, Receive, &number);
} // number gets destroyed here
pthread_create(&threadClient[clientNumber], 0, Receive, &conn[clientNumber] );
void* Receive(void* arg)
{
connection_t * conn = (connection_t *) arg;
[...]
int r = read(conn->sock, &messageLen, sizeof(int));