提问人:bekahboo 提问时间:11/6/2023 更新时间:11/6/2023 访问量:97
与服务器和客户端的聊天程序,用C语言进行套接字编程
Chat Program with server and client, socket programming in C
问:
我打算使用带有 client.c 和 server.c 的套接字编写一个简单的聊天程序 以下是我得到的要求:
服务器:
- 接受一个连接
- 通过先接受消息,然后发送用户输入的消息来与客户端聊天。
- 如果客户端消息为“结束”,服务器将关闭连接。
- 否则,请永远继续交换消息。 客户:
- 连接到服务器
- 通过将用户输入字符串发送到服务器,然后向用户显示服务器响应来开始聊天。
- 如果用户输入“end”,客户端会将其发送到服务器并终止连接。
这是我为 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);
}
}
当我运行该程序时,它起初似乎可以工作,提示客户端向服务器发送消息,然后在我按回车键后将该消息发送到服务器。但是,在我尝试从服务器向客户端发送消息后,代码中断并在终端中输出无限循环。它意味着客户端和服务器相互发送消息,直到客户端进入“结束”。
这是我收到的输出::
首先,我启动程序,它提示客户端输入消息,在此处输入图像描述,接下来我输入消息“hello server”并按回车键,服务器收到消息良好,并提示将消息发送回去,在此处输入图像描述接下来我键入消息“hello client”并按回车键,但这是结果输出,在此处输入图像描述
提前感谢您的任何帮助(:
答:
首先,不要使用 scanf 来读取您的输入。我看到你尝试过(也许?)fgets,但显然没有成功,因为它被注释掉了。现在你应该记住,fgets 最多读取 “size”-1 个字符和换行符 (\n) 字符,因此您需要将其从字符串中删除。有不同的方法可以实现这一点,我使用的方法是
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
中的相同更改 请注意,上述更改只是允许程序按预期运行,您仍然需要考虑其他所有事情,因为该程序可能会以无数种方式崩溃或以非预期方式运行。希望这会有所帮助。
评论
read()
read(Socket_FD, &Message_From_Server, strlen(Message_From_Server)
read(Socket_FD, &Message_From_Server, sizeof Message_From_Server
"end"
strlen()
write(Socket_FD, &message, sizeof(message))
write(Socket_FD, &message, strlen(message)+1)