Compilation error in writing a client side program - c

I am new to socket programming.I looked at a program in the Tutorialspoint.I made a little changes to the program but while compiling I am encountering errors.I am attaching an image telling about the errors..
In addition, I don't understand what is sin_family and sin_port.Shall I replace them with serv_addr_family and serv_addr_port respectively?
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <netdb.h>
#define portno 5432
int main(int argc, char *argv[])
{
int sockfd,n;
const struct sockaddr_in serv_addr;
const struct hostent *server;
char buffer[256];
if (argc < 3) {
fprintf(stderr,"usage %s hostname port\n", argv[0]);
return;
}
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
return;
}
/* Create a socket point */
bzero((char *)&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy(*server->h_addr,
(char *)&serv_addr.sin_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
sockfd = socket(PF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
perror("ERROR opening socket");
return;
}
/* Now connect to the server */
if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
{
perror("ERROR connecting");
return;
}
/* Now ask for a message from the user, this message
* will be read by server
*/
printf("Please enter the message: ");
bzero(buffer,256);
fgets(buffer,255,stdin);
/* Send message to the server */
n = write(sockfd,buffer,strlen(buffer));
if (n < 0)
{
perror("ERROR writing to socket");
return;
}
/* Now read server response */
bzero(buffer,256);
n = read(sockfd,buffer,255);
if (n < 0)
{
perror("ERROR reading from socket");
return;
}
printf("%s\n",buffer);
return 0;
}

you have to remove const before the stuct.
it's used to configure your socket.(port, ip, ...)
int sockfd,n;
const struct sockaddr_in serv_addr;
const struct hostent *server;
to
int sockfd,n;
struct sockaddr_in serv_addr;
struct hostent *server;

There are a few things to correct here:
Firstly,
const struct sockaddr_in serv_addr;
You won't be able to modify serv_addr as it is read-only.
So you may need to remove the const keyword.
On rectifying the above step. You will still run into undefined-behavior in the following statement.
bcopy(*server->h_addr, (char *)&serv_addr.sin_addr, server->h_length);
Change to to below:
bcopy(server->h_addr, (char *)&serv_addr.sin_addr, server->h_length);
Notice the removal of * in the first argument.
The deference is incorrect.
As per comments, I too recommend usage of memcpy like functions.
As a part of good coding practice. Always return with the proper return-type.
Leads to -Wreturn-type as your main expects an int returned .
Example Change:
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
return;
}
to return -1 maybe.

Related

Linux TCP connection refused

I am doing a TCP connection program and I want to set the address and connection step as a function. The program can be compiled but when I running it the screen displays: ERROR CONNECTION: Connection refused. Could you please help me? Here is the server code:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
void error(char *msg)
{
perror(msg);
exit (1);
}
struct sockaddr_in createSockAddr(int portnum)
{
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(portnum);
return addr;
}
int createServerSocket(struct sockaddr_in serv_addr)
{
int newsockfd;
int sockfd;
int clilen;
sockfd = socket(AF_INET, SOCK_STREAM, 0);//create socket
if (sockfd < 0)
error("ERROR opening socket");
//bind socket
if (bind(sockfd, (struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
error("ERROR on binding");
listen(sockfd,5);//listen
clilen = sizeof(serv_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &serv_addr, &clilen);//accept
if (newsockfd < 0)
error("ERROR on accept");
return newsockfd;
}
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portnum, clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;
if (argc < 2) {
fprintf(stderr,"ERROR, no port provided\n");
exit (2);
}
portnum = atoi(argv[1]);
serv_addr = createSockAddr(portnum);
newsockfd = createServerSocket(serv_addr);
bzero(buffer,256);
n = read(newsockfd,buffer,255);
if (n < 0) error("ERROR reading from socket");
printf("Here is the message: %s\n",buffer);
n = write(newsockfd,"I got your message",18);
if (n < 0) error("ERROR writing to socket");
return 0;
}
Here is the client code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
void error(char *msg)
{
perror(msg);
exit(1);
}
struct sockaddr_in createSockAddr(int portnum)
{
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(portnum);
return addr;
}
int createClientSocket(struct sockaddr_in sockAddr)
{
int sockfd;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");//create socket
if (connect(sockfd,(struct sockaddr *)&sockAddr,sizeof(sockAddr)) < 0)
error("ERROR connecting");
return sockfd;
}
int main(int argc, char *argv[])
{
int sockfd, portnum, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[256];
if (argc < 3) {
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(2);
}
portnum = atoi(argv[2]);
serv_addr = createSockAddr(portnum);
sockfd = createClientSocket(serv_addr);
printf("Please enter the message: ");
bzero(buffer,256);
fgets(buffer,255,stdin);
n = write(sockfd,buffer,strlen(buffer));
if (n < 0)
error("ERROR writing to socket");
bzero(buffer,256);
n = read(sockfd,buffer,255);
if (n < 0)
error("ERROR reading from socket");
printf("%s\n",buffer);
return 0;
}
The only questionable thing I see is that you aren't zeroing the sockaddr_in structs before you assign the fields. Otherwise, it looks fine. It's a little atypical to pass structures around (as opposed to pointers to those structures) in C but I don't see any reason why it wouldn't work. (By "zeroing", I mean memset(&addr, 0, sizeof(addr))).)
The code compiles (with some minor warnings), but works for me (client ignores the first parameter and expects port at the second).
Please, try again, and you can also run the server and client under the supervision of strace which is a great tool to see kernel syscalls that an application performs.

Client-server model using C socket programming (Unix Domain)

I'm new to sockets in any programming language and I have been reading about socket using C programming. I found a tutorial on linuxhowtos that presents an implementation of a socket in the internet domain. But the page also says that there exists a way to implement the sockets in the unix domain. How can the following code (taken from linuxhowtos) can be changed in order to implement the socket in the unix domain?
server.c
/* A simple server in the internet domain using TCP
The port number is passed as an argument */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
void error(const char *msg)
{
perror(msg);
exit(1);
}
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno;
socklen_t clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;
if (argc < 2) {
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0)
error("ERROR on binding");
listen(sockfd,5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr,
&clilen);
if (newsockfd < 0)
error("ERROR on accept");
bzero(buffer,256);
n = read(newsockfd,buffer,255);
if (n < 0) error("ERROR reading from socket");
printf("Here is the message: %s\n",buffer);
n = write(newsockfd,"I got your message",18);
if (n < 0) error("ERROR writing to socket");
close(newsockfd);
close(sockfd);
return 0;
}
client.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
void error(const char *msg)
{
perror(msg);
exit(0);
}
int main(int argc, char *argv[])
{
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[256];
if (argc < 3) {
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname(argv[1]);
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(portno);
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
printf("Please enter the message: ");
bzero(buffer,256);
fgets(buffer,255,stdin);
n = write(sockfd,buffer,strlen(buffer));
if (n < 0)
error("ERROR writing to socket");
bzero(buffer,256);
n = read(sockfd,buffer,255);
if (n < 0)
error("ERROR reading from socket");
printf("%s\n",buffer);
close(sockfd);
return 0;
}
The only thing that I found that has to be changed is that instead of using the struct:
#include <netinet/in.h>
struct sockaddr_in
{
short sin_family; /* must be AF_INET */
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8]; /* Not used, must be zero */
};
Yo have to use the following struct that allows the local inter-process communication:
#include<sys/un.h>
struct sockaddr_un
{
sa_family_t sun_family; /* AF_UNIX */
char sun_path[108]; /* pathname */
};

ERROR connecting: Connection refused

IMPORTANT EDIT: After not changing anything it randomly started working. I have no idea why but thanks for all the help anyway!
I'm trying to learn how to create a client and a server that can interact with each other using C. I've done some research and followed a tutorial and I feel like I have a decent understanding of how it all works, but when I tried running the example the client cannot connect to the server.
Here is the client code:
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <netinet/in.h>
#include <string.h>
int main(int argc, char *argv[])
{
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[256];
if (argc <3) {
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
printf("PORT NUMBER: %d\n", portno);
/* Create a socket point */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
perror("ERROR opening socket");
exit(1);
}
server = gethostbyname(argv[1]);
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(portno);
/* Now connect to the server */
if (connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
{
perror("ERROR connecting");
exit(1);
}
return 0;
}
And here is the server code:
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <netinet/in.h>
#include <string.h>
int main( int argc, char *argv[] )
{
int sockfd, newsockfd, portno, clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;
/* First call to socket() function */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("ERROR opening socket");
exit(1);
}
printf("Successfully opened socket\n");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = 5771;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
/* Now bind the host address using bind() call.*/
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
perror("ERROR on binding");
exit(1);
}
printf("Successfully bound socket\n");
/* Now start listening for the clients, here process will
* go in sleep mode and will wait for the incoming connection
*/
printf("Commence listening\n");
listen(sockfd,50);
clilen = sizeof(cli_addr);
/* Accept actual connection from the client */
newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
if (newsockfd < 0) {
perror("ERROR on accept");
exit(1);
}
printf("CONNECTED.\n");
return 0;
}
The output from the server is the following:
Successfully opened socket
Successfully bound socket
Commence Listening
I read some other questions asked here related to the connection refused error and they said that the most likely cause of the error was that the port wasn't open. But if my server is making it all the way to the listening step, shouldn't that mean that the port is in fact open? I don't think it has to do with passing in the wrong IP address to the client because I've tried passing in an incorrect IP address and it errors well before the connection refused.
Does anyone have any insight as to why I'm receiving this error?

C socket program error

This is my C client code. Somehow it is not working. It worked when I tried with argument passing.
I want the program to ask user to give hostname then it will ask for portname and then the message to send:
Enter hostname: localhost
Enter portname: 56456
Enter message : Hi user
Enter message : What's up
Enter message : How are you
And once the host and port given it should not ask for again (until restart the program). I tried with do while loop, but it is not working.
On server it will display the sent message
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
void error(const char *msg)
{
perror(msg);
exit(0);
}
//int main(int argc, char *argv[])
int main()
{
char *argv[256];
int argc;
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
printf("\n\nEnter Hostname\n\n");
fgets(argv[0],256,stdin);
char buffer[256];
if (argc < 3) {
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname(argv[1]);
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(portno);
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
printf("Please enter the message: ");
bzero(buffer,256);
//buffer = tempFunc();
fgets(buffer,255,stdin);
printf("\n\nHere Goes the output\n%s",buffer);
n = write(sockfd,buffer,strlen(buffer));
if (n < 0)
error("ERROR writing to socket");
bzero(buffer,256);
n = read(sockfd,buffer,255);
if (n < 0)
error("ERROR reading from socket");
printf("%s\n",buffer);
close(sockfd);
return 0;
}
First, do not use char * argv[256]
char buffer[256];
printf("\n\nEnter Hostname\n\n");
fgets(buffer,256,stdin);
Then check Removing trailing newline character from fgets() input to deal with fgets.
For an infinite loop, don't do
int a=2; // Useless declaration
do
{
// Your code
}while(a=2) // I guess you wanted (a == 2)
use:
while(1)
{
// Your code
}
Or
for(;;)
{
// Your code
}
It seems that you need a little bit of training, try some tutorials, look for good practices in C, enable warning flags on compilation and learn to use a debugger like gdb.
P.S:
https://stackoverflow.com/help/asking
https://stackoverflow.com/help/answering
Let's fix some basic things first.
Your argv was an array of pointers, pointing to some arbitrary place in memory, here your program could crash.
Next thing is, when you're reading input with fgets, you are reading the \n, too. So localhost\n isn't a valid hostname. Overwrite the last character with an binary zero, to remove the \n.
int main()
{
char hostname[256];
char port[16];
char buffer[256];
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
printf("\n\nEnter Hostname\n\n");
fgets(hostname, 256,stdin);
hostname[ strlen(hostname) - 1 ] = '\0';
fgets(port, 16, stdin);
port[ strlen(port) - 1] = '\0';
portno = atoi(port);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname(hostname);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
//...
}
For command line argument you should not declare argc and argv again! Try this-
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
void error(const char *msg)
{
perror(msg);
exit(0);
}
int main(int argc, char *argv[])
{
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[256];
if (argc < 3) {
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname(argv[1]);
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(portno);
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
printf("Please enter the message: ");
bzero(buffer,256);
//buffer = tempFunc();
fgets(buffer,255,stdin);
printf("\n\nHere Goes the output\n%s",buffer);
n = write(sockfd,buffer,strlen(buffer));
if (n < 0)
error("ERROR writing to socket");
bzero(buffer,256);
n = read(sockfd,buffer,255);
if (n < 0)
error("ERROR reading from socket");
printf("%s\n",buffer);
close(sockfd);
return 0;
}
and add the do while loop where you want!
Here is the code that works with loop. Thanks to #Coconop
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
void error(const char *msg)
{
perror(msg);
exit(0);
}
int main()
{
char hostname[256];
char port[16];
char buffer[256];
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
printf("\n\nEnter Hostname\n\n");
fgets(hostname, 256,stdin);
hostname[ strlen(hostname) - 1 ] = '\0';
fgets(port, 16, stdin);
port[ strlen(port) - 1] = '\0';
portno = atoi(port);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
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(portno);
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
int a=2;
do {
printf("Please enter the message: ");
bzero(buffer,256);
//buffer = tempFunc();
fgets(buffer,255,stdin);
printf("\n\nHere Goes the output\n%s",buffer);
n = write(sockfd,buffer,strlen(buffer));
}while(a=2);
if (n < 0)
error("ERROR writing to socket");
bzero(buffer,256);
n = read(sockfd,buffer,255);
if (n < 0)
error("ERROR reading from socket");
printf("%s\n",buffer);
close(sockfd);
return 0;
}

Socket multithreading Implementation C

I am working on a implementing a multithread multi client single server socket in C. However for whatever reason currently the program, when using pthread_create() to create a new thread, it does not advance past that line of code. I have put print lines before and after this line of code and all of the print lines before hand print fine but none of them after print. This leads me to believe that pthread_create() is somehow buggy. The strange thing about this is I can have 1 client connect and successfully sent/receive data from the server but because the loop that the listen() command is in is not advancing I cannot take on additional clients. I appreciate your help in this matter.
Server Code
#include <stdio.h>
#include <stdlib.h> //for IOs
#include <string.h>
#include <unistd.h>
#include <sys/types.h> //for system calls
#include <sys/socket.h> //for sockets
#include <netinet/in.h> //for internet
#include <pthread.h>
void error(const char *msg)
{
perror(msg);
exit(1);
}
void *threadFunc(int mySockFd)
{
int n;
char buffer[256];
do
{
bzero(buffer,256);
n = read(mySockFd,buffer,255);
if (n < 0)
{
error("ERROR reading from socket");
}
else if(strcmp(buffer, "EXIT\n") == 0)
{
printf("Exit by user\n");
pthread_exit(NULL);
}
else
{
printf("Here is the message: %s\n",buffer);
n = write(mySockFd,"I got your message",18);
if (n < 0)
{
error("ERROR writing to socket");
}
}
}while(n >= 0);
}
int main(int argc, char *argv[])
{
int sockfd;
int newsockfd;
int portno;
pthread_t pth;
int n; /*n is the return value for the read() and write() calls; i.e. it contains the number of characters read or written.*/
int i = 0;
printf("after var decl");
socklen_t clilen; /*clilen stores the size of the address of the client. This is needed for the accept system call.*/
char buffer[256]; /*The server reads characters from the socket connection into this buffer.*/
struct sockaddr_in serv_addr;
struct sockaddr_in cli_addr;
if (argc < 2)
{
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
error("ERROR opening socket");
}
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
{
error("ERROR on binding");
}
do
{
printf("before listen");
listen(sockfd,5);
printf("after listen");
clilen = sizeof(cli_addr);
printf("before accept");
newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr,&clilen);
printf("after accept");
pthread_create(&pth,NULL,threadFunc(newsockfd),(void*) &i);
printf("after pthread create");
if (newsockfd < 0)
{
error("ERROR on accept");
}
}while(1 == 1);
bzero(buffer,256);
n = read(newsockfd,buffer,255);
if (n < 0)
{
error("ERROR reading from socket");
}
printf("Here is the message: %s\n",buffer);
if (n < 0) error("ERROR writing to socket");
close(newsockfd);
close(sockfd);
return 0;
and here is the Client Code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h> /*The file netdb.h defines the structure hostent, which will be used below.*/
void error(const char *msg)
{
perror(msg);
exit(0);
}
int main(int argc, char *argv[])
{
int sockfd;
int portno;
int n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[256];
if (argc < 3)
{
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
error("ERROR opening socket");
}
server = gethostbyname(argv[1]);
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(portno);
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
{
error("ERROR connecting");
}
do
{
printf("Please enter the message: ");
bzero(buffer,256);
fgets(buffer,255,stdin);
n = write(sockfd,buffer,strlen(buffer));
if(strcmp(buffer,"EXIT\n") == 0)
{
printf("Connection Terminated\n");
break;
}
if (n < 0)
{
error("ERROR writing to socket");
}
bzero(buffer,256);
n = read(sockfd,buffer,255);
printf("%s\n",buffer);
if (n < 0)
{
error("ERROR reading from socket");
printf("%s\n",buffer);
}
}while(1 == 1);
close(sockfd);
return 0;
}
Two errors:
You are casting too much, the only place here should be the inaddr stuff.
You are not listening to your compiler, crank up the warning level.
Now, the problem (or maybe just one?) is actually this:
pthread_create(&pth,NULL,threadFunc(newsockfd),(void*) &i);
This will call threadFunc(newsockfd) and pass the result to pthread_create. The second part will never happen though, because that function calls pthread_exit or falls off the end without returning anything, which could cause anything to happen.
Your server code isn't displaying the printf statements reliably is because you didn't end the strings passed to printf with a "\n".
Change all of your printf statements to include a trailing \n such that output will be "flushed" immediately. E.g.
Instead of:
printf("after pthread create");
Do this:
printf("after pthread create\n");
Repeat that fix for all of your printf statements. And then the program flow will be more readily visible as clients connect to it.
There's probably about 5 or 6 other bugs in your code. The main one that I want to call out is just because the client sent 4 bytes of "EXIT", doesn't mean the TCP stream won't fragment that into "EX" and "IT" across two seperate read calls depending on the state of the intertubes. Always write your protocol code as if read/recv were only going to return one char at a time. OR just use MSG_WAITALL with recv() so that you always read the chunk size.

Resources