I am building a chat program between a client and a server in C language. Client will connect to server, sends to it a message. Then server will response that meesage.
If there is another client connects to server, the new connection will be created a new thread. So I use pthread.h to build a multi-threaded chat program in C. Please see the server.c and client.c code below to get more details.
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;
}
OK, I builded the *.c files successfully in Linux environment by using terminal.
I used this command line to build server.c
gcc server.c -o server.out -pthread
and use this one to build client.c
gcc client.c -o client.out
Then, I call server.out to run the server:
./server.out
and run client.out
./client.out
BUT, at the time I run server.out, I got the error:
Segmentation fault (core dumped)
Guys, could you share with me your experiences about this. Is my code wrong in somewhere?
This line is passing NULL as the argument of the handler
re = pthread_create(&interrupt, NULL, clientHandler, NULL);
It should be:
re = pthread_create(&interrupt, NULL, clientHandler, &newsockfd);
as Sourav Ghosh comments.
You need to pass newsockt id to the new thread created.
so change
re = pthread_create(&interrupt, NULL, clientHandler, (void*)&newsockfd);
I have added 3rd argument here
typecasting with (void*) will not give you one warning :)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.