C 聊天程序报错 Segmentation fault (core dumped)
C chat program get an error Segmentation fault (core dumped)
我正在用 C 语言构建一个客户端和服务器之间的聊天程序。客户端将连接到服务器,向其发送消息。然后服务器将响应该信息。
如果有另一个客户端连接到服务器,新连接将创建一个新线程。所以我使用pthread.h在C中构建了一个多线程聊天程序。请参阅下面的server.c和client.c代码以获取更多详细信息。
server.c
#include <pthread.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define PORT 7778
void error(char *msg){
perror(msg);
exit(1);
}
void *clientHandler(void*);
int main(){
printf("INFO enter the main()\n");
int sockfd, newsockfd, clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n, threadID;
pthread_t interrupt;
printf("INFO before calling socket()\n");
sockfd = socket(AF_INET, SOCK_STREAM, 0);
printf("INFO after calling socket()\n");
if(sockfd < 0)
error("ERROR opening socket\n");
printf("INFO before calling bzero()\n");
bzero((char*) &serv_addr, sizeof(serv_addr));
printf("INFO after calling socket()\n");
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(PORT);
printf("INFO after assigning Internet info\n");
if(bind(sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) < 0)
{
error("ERROR on binding\n");
return 0;
}
printf("INFO before calling listen()\n");
listen(sockfd, 5);
printf("INFO before entering While(1)\n");
while(1)
{
int re;
clilen = sizeof(cli_addr);
printf("INFO before calling accept()\n");
newsockfd = accept(sockfd, (struct sockaddr*)&cli_addr, &clilen);
if(newsockfd < 0){
error("ERROR on accepting\n");
return 0;
}
printf("INFO before calling pthread_create()\n");
re = pthread_create(&interrupt, NULL, clientHandler, NULL);
if(re){
printf("ERROR return code from the pthread_create() is %d\n", re);
}
}
printf("INFO before calling pthread_exit(NULL)\n");
pthread_exit(NULL);
return 0;
}
void *clientHandler(void *param){
int n, newsockfd;
newsockfd = *((int*)param);
char buffer[256];
bzero(buffer, 256);
while(1){
n = read(newsockfd, buffer, 255);
if(n < 0){
error("ERROR reading from socket\n");
pthread_exit(NULL);
}
printf("Server received the message: %s", buffer);
n = write(newsockfd, "Server got it\n", 18);
if(n < 0){
error("ERROR writing to socket\n");
pthread_exit(NULL);
}
}
}
client.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define PORT 7778
#define HOSTNAME "127.0.0.1"
void error(char*msg){
perror(msg);
exit(1);
}
int main(){
int sockfd, n;
struct sockaddr_in serv_addr;
struct hostent* server;
//char *hostname = "127.0.0.1";
char buffer[256];
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0)
error("ERROR opening socket\n");
server = gethostbyname(HOSTNAME);
if(server == NULL){
fprintf(stderr,"ERROR no such host\n");
exit(0);
}
bzero((char*) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char*)server->h_addr, (char*)&serv_addr.sin_addr.s_addr, server->h_length);
serv_addr.sin_port = htons(PORT);
if(connect(sockfd, &serv_addr, sizeof(serv_addr)) < 0){
error("ERROR connecting\n");
return 0;
}
while(1)
{
printf("Please enter the message: ");
bzero(buffer, 256);
fgets(buffer, 255, stdin);
n=write(sockfd, buffer, strlen(buffer));
if(n < 0){
error("ERROR reading from socket\n");
return 0;
}
printf("[Server got it] %s\n", buffer);
}
return 0;
}
好的,我使用终端在 Linux 环境中成功构建了 *.c 文件。
我使用这个命令行构建 server.c
gcc server.c -o server.out -pthread
并使用这个来构建 client.c
gcc client.c -o client.out
然后,我调用 server.out 到 运行 服务器:
./server.out
和运行client.out
./client.out
但是,当时我 运行 server.out,我得到了错误:
Segmentation fault (core dumped)
小伙伴们,能不能分享一下你们在这方面的经验。我的代码是不是哪里错了?
此行将 NULL 作为处理程序的参数传递
re = pthread_create(&interrupt, NULL, clientHandler, NULL);
应该是:
re = pthread_create(&interrupt, NULL, clientHandler, &newsockfd);
如 Sourav Ghosh 评论。
您需要将 newsockt id 传递给创建的新线程。
所以改变
re = pthread_create(&interrupt, NULL, clientHandler, (void*)&newsockfd);
我在这里添加了第三个参数
使用 (void*) 进行类型转换不会给您一个警告:)
我正在用 C 语言构建一个客户端和服务器之间的聊天程序。客户端将连接到服务器,向其发送消息。然后服务器将响应该信息。
如果有另一个客户端连接到服务器,新连接将创建一个新线程。所以我使用pthread.h在C中构建了一个多线程聊天程序。请参阅下面的server.c和client.c代码以获取更多详细信息。
server.c
#include <pthread.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define PORT 7778
void error(char *msg){
perror(msg);
exit(1);
}
void *clientHandler(void*);
int main(){
printf("INFO enter the main()\n");
int sockfd, newsockfd, clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n, threadID;
pthread_t interrupt;
printf("INFO before calling socket()\n");
sockfd = socket(AF_INET, SOCK_STREAM, 0);
printf("INFO after calling socket()\n");
if(sockfd < 0)
error("ERROR opening socket\n");
printf("INFO before calling bzero()\n");
bzero((char*) &serv_addr, sizeof(serv_addr));
printf("INFO after calling socket()\n");
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(PORT);
printf("INFO after assigning Internet info\n");
if(bind(sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) < 0)
{
error("ERROR on binding\n");
return 0;
}
printf("INFO before calling listen()\n");
listen(sockfd, 5);
printf("INFO before entering While(1)\n");
while(1)
{
int re;
clilen = sizeof(cli_addr);
printf("INFO before calling accept()\n");
newsockfd = accept(sockfd, (struct sockaddr*)&cli_addr, &clilen);
if(newsockfd < 0){
error("ERROR on accepting\n");
return 0;
}
printf("INFO before calling pthread_create()\n");
re = pthread_create(&interrupt, NULL, clientHandler, NULL);
if(re){
printf("ERROR return code from the pthread_create() is %d\n", re);
}
}
printf("INFO before calling pthread_exit(NULL)\n");
pthread_exit(NULL);
return 0;
}
void *clientHandler(void *param){
int n, newsockfd;
newsockfd = *((int*)param);
char buffer[256];
bzero(buffer, 256);
while(1){
n = read(newsockfd, buffer, 255);
if(n < 0){
error("ERROR reading from socket\n");
pthread_exit(NULL);
}
printf("Server received the message: %s", buffer);
n = write(newsockfd, "Server got it\n", 18);
if(n < 0){
error("ERROR writing to socket\n");
pthread_exit(NULL);
}
}
}
client.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define PORT 7778
#define HOSTNAME "127.0.0.1"
void error(char*msg){
perror(msg);
exit(1);
}
int main(){
int sockfd, n;
struct sockaddr_in serv_addr;
struct hostent* server;
//char *hostname = "127.0.0.1";
char buffer[256];
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0)
error("ERROR opening socket\n");
server = gethostbyname(HOSTNAME);
if(server == NULL){
fprintf(stderr,"ERROR no such host\n");
exit(0);
}
bzero((char*) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char*)server->h_addr, (char*)&serv_addr.sin_addr.s_addr, server->h_length);
serv_addr.sin_port = htons(PORT);
if(connect(sockfd, &serv_addr, sizeof(serv_addr)) < 0){
error("ERROR connecting\n");
return 0;
}
while(1)
{
printf("Please enter the message: ");
bzero(buffer, 256);
fgets(buffer, 255, stdin);
n=write(sockfd, buffer, strlen(buffer));
if(n < 0){
error("ERROR reading from socket\n");
return 0;
}
printf("[Server got it] %s\n", buffer);
}
return 0;
}
好的,我使用终端在 Linux 环境中成功构建了 *.c 文件。
我使用这个命令行构建 server.c
gcc server.c -o server.out -pthread
并使用这个来构建 client.c
gcc client.c -o client.out
然后,我调用 server.out 到 运行 服务器:
./server.out
和运行client.out
./client.out
但是,当时我 运行 server.out,我得到了错误:
Segmentation fault (core dumped)
小伙伴们,能不能分享一下你们在这方面的经验。我的代码是不是哪里错了?
此行将 NULL 作为处理程序的参数传递
re = pthread_create(&interrupt, NULL, clientHandler, NULL);
应该是:
re = pthread_create(&interrupt, NULL, clientHandler, &newsockfd);
如 Sourav Ghosh 评论。
您需要将 newsockt id 传递给创建的新线程。
所以改变
re = pthread_create(&interrupt, NULL, clientHandler, (void*)&newsockfd);
我在这里添加了第三个参数
使用 (void*) 进行类型转换不会给您一个警告:)