我打算使用 client.c 和 server.c 的套接字编写一个简单的聊天程序 这是我收到的要求:
服务器:
这是我为 server.c 编写的代码:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/ip.h>
#include <string.h>
int main(){
unsigned short port;
struct sockaddr_in Client_info;
socklen_t Client_Info_Len;
struct sockaddr_in Server_info;
int Socket_Serv_FD, Socket_Client_FD;
int result;
char message[100];
char Message_From_Client[100];
port = 23232;
printf("Server initiating connection ... \n");
// create socket
Socket_Serv_FD = socket(AF_INET, SOCK_STREAM, 0);
// check for failure
if(Socket_Serv_FD < 0){
printf("Socket creation failed.");
return -1;
}
// binding information
Server_info.sin_family = AF_INET;
Server_info.sin_port = port;
Server_info.sin_addr.s_addr = INADDR_ANY;
// bind with port to the socket
result = bind(Socket_Serv_FD, (struct sockaddr *)&Server_info, sizeof(struct sockaddr_in));
if(result < 0){
printf("Binding socket failed.");
return -1;
}
// listen for connections on socket
result = listen(Socket_Serv_FD, 0);
if(result < 0){
printf("Listen socket failed");
return -1;
}
// accept when a connection occurs
Socket_Client_FD = accept(Socket_Serv_FD, (struct sockaddr *)&Client_info, &Client_Info_Len);
if(Socket_Client_FD < 0){
printf("Socket connection failed.");
return -1;
}
while(1){
// read message from client
result = read(Socket_Client_FD, &Message_From_Client, sizeof(Message_From_Client));
if(result < 0){
printf("Socket failed.");
return -1;
}
printf("Message from client >> %s \n", Message_From_Client);
// close socket when user enters 'end'!
if(strcmp(Message_From_Client, "end") == 0){
printf("Closing connection ... \n");
break;
}
// prompt for message to send to client
printf("Type a message to the client : ");
scanf("%[^\n]", message);
//fgets(message, 100, stdin);
// send message to client
result = write(Socket_Client_FD, &message, strlen(message));
if(result < 0){
printf("Message failed.");
return -1;
}
}
close(Socket_Serv_FD);
close(Socket_Client_FD);
return 0;
}
这是我的 client.c 代码:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include <string.h>
int main(){
struct sockaddr_in Server_info;
int Socket_FD;
int result;
char message[100];
char Message_From_Server[100];
int port = 23232;
printf("Initiating connection ... \n");
// create a socket
Socket_FD = socket(AF_INET, SOCK_STREAM, 0);
if(Socket_FD == -1){
printf("Socket creation failed.");
return -1;
}
// bind information
Server_info.sin_family = AF_INET;
Server_info.sin_port = port;
Server_info.sin_addr.s_addr = inet_addr("127.0.0.1");
// listen for connections
result = connect(Socket_FD, (struct sockaddr *)&Server_info, sizeof(struct sockaddr_in));
if(result < 0){
printf("Connect socket failed.");
return -1;
}
while(1){
// get input message from user
printf("Type a message to server or 'end' to close connection : ");
scanf("%[^\n]", message);
//fgets(message, 100, stdin);
// send to server
result = write(Socket_FD, &message, sizeof(message));
if(result < 0){
printf("Message failed.");
return -1;
}
// close socket when user enters 'end'!
if(strcmp(message, "end") == 0){
printf("Closing connection ... ");
close(Socket_FD);
return 0;
}
// receive from server
result = read(Socket_FD, &Message_From_Server, strlen(Message_From_Server));
if(result < 0){
printf("Message failed.");
return -1;
}
printf("Message from server >> %s \n", Message_From_Server);
}
}
当我运行该程序时,它似乎首先工作,提示客户端向服务器发送消息,然后在我按回车键后将该消息发送到服务器。但是,在我尝试从服务器将消息发送回客户端后,代码中断并在终端中输出无限循环。这意味着客户端和服务器之间会稳定地来回发送消息,直到客户端输入“结束”。
这是我收到的输出::
首先我启动程序,它会提示客户端输入消息 接下来我输入 msg 'hello server' 并按 Enter 键,服务器接收到 msg 正常并提示发送回 msg 接下来我输入 msg 'hello client' 并按 Enter 键,但这是结果输出
提前感谢您的任何帮助(:
首先,不要使用 scanf 来读取您的输入。我看到您尝试(也许?)使用 fgets 但显然没有成功,因为它已被注释掉。现在您应该记住 fgets 最多读取“size”-1 个字符和换行符 ( ) 字符,因此您需要将其从字符串中删除。有不同的方法可以实现这一目标,我使用的是
message[strcspn(message, "\n")] = 0;
同时 scanf 只会解析与其格式说明符匹配的任何内容,其他所有内容都留在缓冲区中供您管理。当我尝试使用 scanf 运行代码时,我得到了一个无限循环,就像你所做的那样。 现在,我还想提一下,我没有使用 write/read,而是使用了 send/recv,当在函数调用中使用 0 标志时,它应该与 write/read 几乎相同,也许对您来说会有所不同。 即,在client.c
result = write(Socket_FD, &message, sizeof(message));
成为
result = send(Socket_FD, message, sizeof(message),0);
和
result = read(Socket_FD, &Message_From_Server, strlen(Message_From_Server);
成为
result = recv(Socket_FD, Message_From_Server, sizeof(Message_From_Server),0);
server.c 中的相同更改
请注意,上述更改只是允许您的程序按照最初的预期运行,您仍然需要考虑其他所有事情,因为该程序可能会以无数种方式崩溃或以非预期方式运行。希望这有帮助。