我需要使用套接字在C中编写聊天程序,但我遇到了问题。
我有三个文件:server,client1,client2。我的初步计划: - Client1将消息发送到服务器
当任一客户端发送"退出"。
时,循环结束我的问题用几句话说:
第一次交换成功(Client1 - > Client2,然后Client2到Client1)
但是,在Client2将其第一条消息发送给Client1后,他并没有等待Client1的响应。他写道" Client1:"用空行留言,然后立即打开他自己的" Client2:"消息字段。
上帝的名字在这里有什么不对吗?
Client1.c
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
int compare_strings(char a[], char b[])
{
int c = 0;
while (a[c] == b[c])
{
if (a[c] == '\0' || b[c] == '\0')
break;
c++;
}
if (a[c] == '\0' && b[c] == '\0')
return 0;
else
return -1;
}
int main() {
int clientSocket;
char buffer[1024];
struct sockaddr_in serverAddr;
socklen_t addr_size;
int cmdEXIT = 0;
clientSocket = socket(PF_INET, SOCK_STREAM, 0);
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(7891);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);
addr_size = sizeof serverAddr;
connect(clientSocket, (struct sockaddr *) &serverAddr, addr_size);
while (cmdEXIT == 0)
{
printf("Client 1 : ");
scanf(" %[^\n]s", buffer);
send(clientSocket,buffer,sizeof buffer - 1,0);
if (compare_strings(buffer, "exit")==-1)
{
memset(&buffer[0], 0, sizeof(buffer));
recv(clientSocket, buffer, sizeof buffer - 1, 0);
if (compare_strings(buffer, "exit")==-1)
{
printf("Client 2 : ");
printf("%s\n", buffer);
memset(&buffer[0], 0, sizeof(buffer));
}
else cmdEXIT=1;
}
else cmdEXIT=1;
}
return 0;
}
Server.c
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
int compare_strings(char a[], char b[])
{
int c = 0;
while (a[c] == b[c])
{
if (a[c] == '\0' || b[c] == '\0')
break;
c++;
}
if (a[c] == '\0' && b[c] == '\0')
return 0;
else
return -1;
}
int main() {
int welcomeSocket, newSocket, Client2;
struct sockaddr_in serverAddr;
struct sockaddr_storage serverStorage;
socklen_t addr_size;
char buffer[1024];
welcomeSocket = socket(PF_INET, SOCK_STREAM, 0);
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(7891);
serverAddr.sin_addr.s_addr = inet_addr("127.0.01");
memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);
bind(welcomeSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));
if (listen(welcomeSocket,5)==0)
printf("Listening\n");
else
printf("Error\n");
addr_size = sizeof serverStorage;
newSocket = accept(welcomeSocket, (struct sockaddr *) &serverStorage, &addr_size);
Client2 = accept(welcomeSocket, (struct sockaddr *) &serverStorage, &addr_size);
int cmdEXIT = 0;
while (cmdEXIT == 0)
{
recv(newSocket, buffer, 1024, 0);
printf ("%s\nEnvoie au Client2\n", buffer);
send(Client2,buffer,1024,0);
if (compare_strings(buffer, "exit")==0)
{
cmdEXIT = 1;
}
else
{
memset(&buffer[0], 0, sizeof(buffer));
recv(Client2, buffer, 1024, 0);
printf ("%s\nEnvoie au Client1\n", buffer);
send(newSocket,buffer,1024,0);
if (compare_strings(buffer, "exit")==0)
{
cmdEXIT = 1;
}
}
}
return 0;
}
Client2.c
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
int compare_strings(char a[], char b[])
{
int c = 0;
while (a[c] == b[c])
{
if (a[c] == '\0' || b[c] == '\0')
break;
c++;
}
if (a[c] == '\0' && b[c] == '\0')
return 0;
else
return -1;
}
int main() {
int clientSocket;
char buffer[1024];
struct sockaddr_in serverAddr;
socklen_t addr_size;
int cmdEXIT = 0;
clientSocket = socket(PF_INET, SOCK_STREAM, 0);
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(7891);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);
addr_size = sizeof serverAddr;
connect(clientSocket, (struct sockaddr *) &serverAddr, addr_size);
while (cmdEXIT == 0)
{
recv(clientSocket, buffer, sizeof buffer - 1, 0);
if (compare_strings(buffer, "exit")==-1)
{
printf("Client 1 : ");
printf("%s\n", buffer);
memset(&buffer[0], 0, sizeof(buffer));
printf("Client 2 : ");
scanf(" %[^\n]s", buffer);
send(clientSocket,buffer,sizeof buffer - 1,0);
if (compare_strings(buffer, "exit")==-1)
{
memset(&buffer[0], 0, sizeof(buffer));
}
else cmdEXIT = 1;
}
else cmdEXIT = 1;
}
return 0;
}
结果截图:
Client 2 being too bossy and not waiting for his turn to speak
答案 0 :(得分:1)
免责声明:我自己没有运行您的代码,因此以下分析可能是错误的。
我建议您检查recv
的返回值,该值会在出错时返回-1
。如果recv
在此行Client2.c中遇到错误:在while循环开始时recv(clientSocket, buffer, sizeof buffer - 1, 0);
,则缓冲区将保持清零状态。
因此,客户端2不会等待客户端1的消息,只会打印来自客户端1的消息的空字符串。
如果有任何帮助或需要更多帮助,请告诉我。如果上述情况属实,则应确保连接不会中断,等等。
答案 1 :(得分:1)
所以,正如前面评论中所承诺的,这是我的解决方案。简而言之:每次我测试recv的价值是什么。如果它等于1,则表示没有收到消息,&#34;该行是免费的&#34;并且客户端可以键入自己的消息。否则,他必须显示收到的消息,然后才能发送他自己的文本。
Client1.c
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
//fonction pour comparer deux strings : renvoie 0 si les valeurs sont égales
//et -1 sinon
int compare_strings(char a[], char b[])
{
int c = 0;
while (a[c] == b[c])
{
if (a[c] == '\0' || b[c] == '\0')
break;
c++;
}
if (a[c] == '\0' && b[c] == '\0')
return 0;
else
return -1;
}
int main() {
//déclaration des variables
int clientSocket;
char buffer[1024];
struct sockaddr_in serverAddr;
socklen_t addr_size;
int cmdEXIT = 0;
//paramètrage du socket
clientSocket = socket(PF_INET, SOCK_STREAM, 0);
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(7891);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);
addr_size = sizeof serverAddr;
//connection au serveur
connect(clientSocket, (struct sockaddr *) &serverAddr, addr_size);
//premier message du Client1
printf("Client 1 : ");
scanf(" %[^\n]s", buffer);
send(clientSocket,buffer,sizeof buffer - 1,0);
//continuer à envoyer et recevoir des messages
//tant qu'un des clients n'envoive pas "exit"
while (cmdEXIT == 0)
{
//si le message envoyé n'est pas "exit"
if (compare_strings(buffer, "exit")==-1)
{
//vider le buffer
memset(&buffer[0], 0, sizeof(buffer));
//la valeur de recv qui est égale a 1 si recv n'a pas
//encore reçu de message
//sinon, elle est égale au nombre de bits reçu
int recvValue = recv(clientSocket, buffer, sizeof buffer - 1, 0);
//si recv n'est pas égal a 1 => un message a été reçu
if (recvValue != 1)
{
//si le contenu n'est pas "exit"
if (compare_strings(buffer, "exit")==-1)
{
//afficher le message du Client2
printf("Client 2 : ");
printf("%s\n", buffer);
//vider le buffer
memset(&buffer[0], 0, sizeof(buffer));
}
//si Client2 a envoyé "exit"
else cmdEXIT=1;
}
//si rcv est égal a 1 => pas de message reçu
else
{
//Client1 peut saisir son message
printf("Client 1 : ");
scanf(" %[^\n]s", buffer);
//et l'envoyer à Client2
send(clientSocket,buffer,sizeof buffer - 1,0);
}
}
//sinon finir la boucle
else cmdEXIT=1;
}
return 0;
}
Server.c
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
//fonction pour comparer deux strings : renvoie 0 si les valeurs sont égales
//et -1 sinon
int compare_strings(char a[], char b[])
{
int c = 0;
while (a[c] == b[c])
{
if (a[c] == '\0' || b[c] == '\0')
break;
c++;
}
if (a[c] == '\0' && b[c] == '\0')
return 0;
else
return -1;
}
int main() {
//déclaration des variables : Serveur et deux Clients
int welcomeSocket, Client1, Client2;
struct sockaddr_in serverAddr;
struct sockaddr_storage serverStorage;
socklen_t addr_size;
char buffer[1024];
//paramètrage du Serveur
welcomeSocket = socket(PF_INET, SOCK_STREAM, 0);
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(7891);
serverAddr.sin_addr.s_addr = inet_addr("127.0.01");
memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);
bind(welcomeSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));
//Serveur à l'écoute
if (listen(welcomeSocket,5)==0)
printf("Listening\n");
else
printf("Error\n");
//lier le serveur et les deux clients
addr_size = sizeof serverStorage;
Client1 = accept(welcomeSocket, (struct sockaddr *) &serverStorage, &addr_size);
Client2 = accept(welcomeSocket, (struct sockaddr *) &serverStorage, &addr_size);
int cmdEXIT = 0;
//continuer à recevoir et envoyer des messages
//tant qu'un des clients n'envoive pas "exit"
while (cmdEXIT == 0)
{
//recevoir le message de Client1
recv(Client1, buffer, 1024, 0);
//le renvoyer a Client2
printf ("%s\nEnvoie au Client2\n", buffer);
send(Client2,buffer,1024,0);
//sortir de la boucle si Client1 a envoyé "exit"
if (compare_strings(buffer, "exit")==0)
{
cmdEXIT = 1;
}
//sinon
else
{
//vider le buffer
memset(&buffer[0], 0, sizeof(buffer));
//recevoir le message de Client2
recv(Client2, buffer, 1024, 0);
//le renvoyer a Client1
printf ("%s\nEnvoie au Client1\n", buffer);
send(Client1,buffer,1024,0);
//si Client2 a envoyé "exit"
if (compare_strings(buffer, "exit")==0)
{
cmdEXIT = 1;
}
}
}
return 0;
}
Client2.c
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
//fonction pour comparer deux strings : renvoie 0 si les valeurs sont egales et -1 sinon
int compare_strings(char a[], char b[])
{
int c = 0;
while (a[c] == b[c])
{
if (a[c] == '\0' || b[c] == '\0')
break;
c++;
}
if (a[c] == '\0' && b[c] == '\0')
return 0;
else
return -1;
}
int main() {
//déclaration des variables
int clientSocket;
char buffer[1024];
struct sockaddr_in serverAddr;
socklen_t addr_size;
int cmdEXIT = 0;
//paramètrage du socket
clientSocket = socket(PF_INET, SOCK_STREAM, 0);
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(7891);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);
addr_size = sizeof serverAddr;
//connection au serveur
connect(clientSocket, (struct sockaddr *) &serverAddr, addr_size);
//continuer à envoyer et recevoir des messages
//tant qu'un des clients n'envoive pas "exit"
while (cmdEXIT == 0)
{
//la valeur de recv qui est égale a 1 si recv n'a pas
//encore reçu de message
//sinon, elle est egale au nombre de bits reçu
int recvValue = recv(clientSocket, buffer, sizeof buffer - 1, 0);
//si recv n'est pas égal a 1 => un message a été reçu
if (recvValue != 1)
{
//si le contenu n'est pas "exit"
if (compare_strings(buffer, "exit")==-1)
{
//afficher le message du Client1
printf("Client 1 : ");
printf("%s\n", buffer);
memset(&buffer[0], 0, sizeof(buffer));
}
//sinon sortir de la boucle
else cmdEXIT = 1;
}
else
{
//Client2 peut saisir son message
printf("Client 2 : ");
scanf(" %[^\n]s", buffer);
//Client2 envoie son message au serveur
send(clientSocket,buffer,sizeof buffer - 1,0);
//si le contenu n'est pas "exit"
if (compare_strings(buffer, "exit")==-1)
{
//vider le buffer
memset(&buffer[0], 0, sizeof(buffer));
}
//sinon sortir de la boucle
else cmdEXIT = 1;
}
}
return 0;
}