I made a TCP Client/Server and I can run it one time. But when I try to run it more than one time, it gives me the following error: "Connection refused". Here's my code.
Client
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main() {
int net_socket = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in net_addr;
net_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
net_addr.sin_family = AF_INET;
net_addr.sin_port = htons(3250);
int connection_state = connect(net_socket, (struct sockaddr*)&net_addr, sizeof(net_addr));
if (connection_state == 0) {
printf("Connected with the server.\n");
}
else {
printf("Connection with the server failed. [%s]\n", strerror(errno));
}
char net_message[256];
recv(net_socket, net_message, sizeof(net_message), 0);
close(net_socket);
shutdown(net_socket, SHUT_RDWR);
return 0;
}
Server
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main() {
int net_socket = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in net_addr;
net_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
net_addr.sin_family = AF_INET;
net_addr.sin_port = htons(3250);
bind(net_socket, (struct sockaddr*)&net_addr, sizeof(net_addr));
listen(net_socket, 1);
struct sockaddr_in cl_addr;
int cl_size = sizeof(cl_addr);
int cl_socket = accept(net_socket, (struct sockaddr*)&cl_addr, (socklen_t*)&cl_size);
int loop = 1;
char net_message[256];
send(cl_socket, net_message, sizeof(net_message), 0);
close(net_socket);
close(cl_socket);
shutdown(net_socket, SHUT_RDWR);
shutdown(cl_socket, SHUT_RDWR);
return 0;
}
I've been trying to solve the problem by many ways but I'm a newbie. Thanks for the help in advance!
The problem is with your server lacking the SO_REUSEADDR socket option which leads to the bind() syscall failing. The reason is, that after a client disconnects from the server, the connection is still known by the system in TIME_WAIT state, to wait for late packets. These lead to the bind() to fail with EADDRINUSE if the above mentioned socket option is not set.
Use the following:
...
int one = 1;
setsockopt(net_socket, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
bind(net_socket, (struct sockaddr*)&net_addr, sizeof(net_addr));
...
and do error checks for all syscalls! That would have shown you the problem much earlier and had saved you much time.
Some more issues:
You are sending an uninitialized buffer net_message
A shutdown on a listen socket isn't sensible at all, since no connection is established on it (this here: shutdown(net_socket, SHUT_RDWR);)
The shutdown on the client socket has - if at all - to be performed before the close(cl_socket);. But it is not necessary at all in that case.
Related
I learn how application works themself by Internet. I wrote a client program which sends a message to a server program, then that message should be printed in a server program, but this message prints into a client program. Here code server program and client program, also header file to redefine some types.
There are not any errors and warning while compiling, so I didn't send a compiling process.
server.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/un.h>
#include "../main_values.h"
int main()
{
int socket_server = socket(AF_INET, SOCK_STREAM, 0); //create a socket server
int opt = 1;
setsockopt(socket_server, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); //set an option to socket to
//if we ends working with
sockaddr_in addr_server; //socket connected with
addr_server.sin_family = AF_INET; //ip address, free ip
addr_server.sin_port = htons(2251);
addr_server.sin_addr.s_addr = inet_addr("127.0.0.222");
int stat = bind(socket_server, (sockaddr *)&addr_server, sizeof(addr_server)); //connecting ip addr and socket
if (stat == -1)
{
perror("ERROR");
}
sockaddr_in addr_client; //create the future client ip stucture
socklen_t len = 0;
listen(socket_server, 15); //set server socket into listening
int socket_client = accept(socket_server, (sockaddr *)&addr_client, &len); //connecting client ip with our socket
if (socket_client == -1)
{
perror("ERROR");
}
char msg[100];
int res = read(socket_server, msg, sizeof(msg)); //getting message from client
printf("MESSAGE FROM CLIENT: %s\n", msg); //printing message from client
shutdown(socket_server, SHUT_RDWR); //closing server socket
return 0;
}
client.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/un.h>
#include "../main_values.h"
int main()
{
int socket_client = socket(AF_INET, SOCK_STREAM, 0); //create a client socket
int opt = 1; //set an option like in a server.c
setsockopt(socket_client, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
sockaddr_in addr_client; //making client ip structure
addr_client.sin_family = AF_INET;
addr_client.sin_port = htons(2250);
addr_client.sin_addr.s_addr = htons(INADDR_ANY);
int stat = bind(socket_client, (sockaddr *)&addr_client, sizeof(addr_client)); //connecting ip and client socket
if (stat == -1)
{
perror("ERROR");
}
sockaddr_in addr_server; //creating a server ip structure
addr_server.sin_family = AF_INET;
addr_server.sin_port = htons(2251);
addr_server.sin_addr.s_addr = inet_addr("127.0.0.222");
int socket_server = connect(socket_client, (sockaddr *)&addr_server, sizeof(addr_server));
if (socket_server == -1) //connecting to server
{
perror("ERROR");
}
char msg[] = "HELLO WORLD!!!!!"; //excample message
int res = write(socket_server, msg, sizeof(msg)); //sending a message to server
shutdown(socket_client, SHUT_RDWR);
return 0;
}
main_values.h
#pragma once
typedef struct sockaddr sockaddr;
typedef struct sockaddr_in sockaddr_in;
terminal_1
ch#ch:~/Рабочий стол/mainc.4/my_server$ ./server.out
MESSAGE FROM CLIENT:
ch#ch:~/Рабочий стол/mainc.4/my_server$
terminal_2
ch#ch:~/Рабочий стол/mainc.4/my_server$ ./client.out
HELLO WORLD!!!!!ch#ch:~/Рабочий стол/mainc.4/my_server$
int socket_server = connect(socket_client, (sockaddr *)&addr_server,
...
int res = write(socket_server, msg, sizeof(msg));
The return code of connect is 0 if the connect succeeded. Thus socket_server is 0. This means a write to file descriptor 0 is done, which is the equivalent to stdin and thus results into a write to the terminal.
The correct code would be to write to socket_client, not socket_server. The naming suggests that there is some confusion of what connect returns, i.e. it returns a status and not a new socket. Please see the documentation for connect for details.
I'm trying to import C programs, which demonstrate TCP socket programming in the Linux environment, into Windows. In the following two programs, the commented out include statements work in Linux and the includes below them are the Windows equivalent that I put. However, when I'm running these two programs, the server and the client produce the following errors respectively.
Error from simple_server
Socket received successfully...Failed to listen...
Error from simple_client
Read Error
All the equivalent Windows includes were taken from a long Stackoverflow searching session itself..:D. However, I'm stuck here not understanding why my server is not running. Any helpful advice and suggestions are highly appreciated.
My code
simple_server.c
// #include <arpa/inet.h>
// #include <sys/socket.h>
// #include <netinet/in.h>
#include <Winsock2.h>
#include <stdio.h>
#include <stdlib.h>
// #include <unistd.h>
#include <io.h>
// Windows equivalent to sleep() in unistd.h
#include <windows.h>
#define sleep(n) Sleep(n*1000)
#define usleep(n) Sleep(n/1000)
#include <errno.h>
#include <string.h>
#include <sys/types.h>
int main (void){
int listenfd, connfd = 0;
struct sockaddr_in serv_addr;
char send_buff[1024];
int numrv;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
printf("Socket received successfully...");
memset(&serv_addr, '0', sizeof(serv_addr));
memset(send_buff, '0', sizeof(send_buff));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htons(INADDR_ANY);
serv_addr.sin_port = htons(50001);
bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
if(listen(listenfd,10) == -1){
printf("Failed to listen..");
return -1;
}
while(1){
connfd = accept(listenfd,(struct sockaddr*)NULL, NULL);
strcpy(send_buff, "Message from the server");
write(connfd, send_buff, strlen(send_buff));
close(connfd);
sleep(1);
}
return 0;
}
simple_client.c
#include <sys/types.h>
// #include <arpa/inet.h>
// #include <sys/socket.h>
// #include <netinet/in.h>
// #include <netdb.h>
#include <Winsock2.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// #include <unistd.h>
#include <io.h>
#include <errno.h>
int main(void){
int sockfd, n =0;
char receive_buffer[1024];
struct sockaddr_in serv_addr;
memset(receive_buffer, '0', sizeof(receive_buffer));
if((sockfd == socket(AF_INET, SOCK_STREAM, 0)) < 0){
printf("Error: couldn't receive socket.");
return -1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(5000);
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
if(connect(sockfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr)) < 0){
}
while ((n = read(sockfd, receive_buffer, sizeof(receive_buffer)-1)) > 0){
receive_buffer[n] = 0;
if(fputs(receive_buffer,stdout) == EOF){
printf("\nError: fputs error");
}
printf("\n");
}
if(n<0){
printf("\n Read Error");
}
return 0;
}
I'm starting to learn unix basics at college, i've got an exercise which says something like:"build a client/server application in C in which: the server (tcp socket) print the ip of the client and the text given, and and it shutdown when receives "exit" as string from the client.
Now I've got conceptual problems, i've written these two C program (ignoring for now the text thing...)which i start in two different linux terminal, but the client do nothing, and the server got stuck. I don't understand the whole address thing, what should i put in there (in client)?
Long story short: I cannot establish a simple connection
SERVER
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
int main (void){
struct sockaddr_in mio_indirizzo;
mio_indirizzo.sin_family= AF_INET;
mio_indirizzo.sin_port=htons(5200);
mio_indirizzo.sin_addr.s_addr = htonl(INADDR_ANY);
int fd = socket(PF_INET,SOCK_STREAM,0);
if (fd<0) perror("socket"),exit(1);
int b=bind(fd,(struct sockaddr *)&mio_indirizzo,sizeof(mio_indirizzo));
if(b<0) perror("bind"),exit(-1);
if((listen(fd,5))<0) perror("listen"),exit(-1);
while(1){
struct sockaddr indirizzo_client;
int fd2=accept(fd, &indirizzo_client,NULL);
if (fd2<0) perror("accept"),exit(-1);
printf("connection accepted\n");
close(fd2);
}
close(fd);
shutdown(fd,SHUT_RDWR);
}
CLIENT
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
int main (void){
int fd;
struct sockaddr_in mio_indirizzo;
mio_indirizzo.sin_family = AF_INET;
mio_indirizzo.sin_port = htons(5200);
inet_aton("Putted here the IP of my machine", &mio_indirizzo.sin_addr);
fd = socket(PF_INET, SOCK_STREAM, 0); // crea un socket
connect(fd, (struct sockaddr *) &mio_indirizzo, sizeof(mio_indirizzo)); // crea la connessione
close(fd); // chiude il socket
}
In your server, for accept():
struct sockaddr indirizzo_client;
int len = sizeof(indirizzo_client);
int fd2=accept(fd, &indirizzo_client, &len);
But actually, your program will just print "connection accepted" and quit. You may use select or threads to communicate between the client and the server.
I've been approaching network programming these days, and I wrote two simple routines to check if I got it right. So I built the server on the desktop and started it, then I built the client on the laptop and I ran it, and everything went as expected. When I tried to run them the second time and on, the server kept looping and the client after two seconds gave "Error connecting!". If I try again after fifteen minutes it works, but then I have to wait again. Where am I wrong? The computers are both connected to my LAN, 79.13.199.165 is the IP of my modem/router, which forwards every incoming connection on port 53124 to the desktop. This problem doesn't occur when running both server and client on the same PC.
server.c
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
int main () {
struct sockaddr_in sa;
sa.sin_family = AF_INET;
sa.sin_port = htons(53124);
sa.sin_addr.s_addr = htonl(INADDR_ANY);
memset(sa.sin_zero, '\0', sizeof(sa.sin_zero));
int mysocket = socket(PF_INET, SOCK_STREAM, 0);
bind(mysocket, (struct sockaddr*)&sa, sizeof(sa));
listen(mysocket, 5);
int inc;
struct sockaddr_in inc_addr;
socklen_t inc_addr_size = sizeof(inc_addr);
inc = accept(mysocket, (struct sockaddr*)&inc_addr, &inc_addr_size);
if (inc != -1) {
printf("accepting client\n");
}
send(inc, "ciao", sizeof("ciao"), 0);
close(inc);
return 0;
}
client.c
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
int main () {
struct sockaddr_in sa;
sa.sin_family = AF_INET;
sa.sin_port = htons(53124);
sa.sin_addr.s_addr = inet_addr("79.13.199.165");
memset(sa.sin_zero, '\0', sizeof(sa.sin_zero));
int mysocket = socket(PF_INET, SOCK_STREAM, 0);
if (mysocket == -1) {
printf("Could not create socket!\n");
}
if (connect(mysocket, (struct sockaddr*)&sa, sizeof(sa)) == -1) {
printf("Error connecting!\n");
}
char message[5];
memset(message, '\0', sizeof(message));
recv(mysocket, message, 5, 0);
printf("%s\n", message);
return 0;
}
When the server closes the socket, a couple of ACK packets get sent backwards and forwards across the connection. There's no way to tell if the last ACK gets delivered successfully, so the connection goes into the TIME_WAIT state for a bit. This basically gives the TCP stack time to wait for any lost packets and throw them away.
It's possible to ignore this and reuse the socket straight away by setting SO_REUSEADDR using setsockopt(). There is a small danger that subsequent connects might get data they weren't supposed to but it shouldn't be a problem for your little test application.
Edit
By the way, one reason why you were probably getting confused by this is that you don't do any error checking on socket() bind() or listen(). The bind() call would certainly return an error and set errno, EINVAL on Linux.
I am learning the Sockets networking API. In this process, I have written a simple Echo server that uses TCP. I wrote the code in such a way that, as long as the server is running, anything typed on the client's console should be echoed back to it. However, I am unable to achieve this. Although, for the first input, I get the echo, from next time onwards, I do not get any message.
I know, we can implement it to run for many clients using fork(), but I want to know the reason behind the blocking of the client, and if possible ways to correct it.
Here is the code for the client:
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <unistd.h>
#define MAXCOUNT 1024
int main(int argc, char* argv[])
{
int sfd;
char msg[MAXCOUNT];
char blanmsg[MAXCOUNT];
struct sockaddr_in saddr;
memset(&saddr,0,sizeof(saddr));
sfd = socket(AF_INET,SOCK_STREAM,0);
saddr.sin_family = AF_INET;
inet_pton(AF_INET,"127.0.0.1",&saddr.sin_addr);
saddr.sin_port = htons(5004);
connect(sfd,(struct sockaddr*) &saddr, sizeof(saddr));
for(; ;) {
memset(msg,0,MAXCOUNT);
memset(blanmsg,0,MAXCOUNT);
fgets(msg,MAXCOUNT,stdin);
send(sfd,msg,strlen(msg),0);
recv(sfd,blanmsg,sizeof(blanmsg),0);
printf("%s",blanmsg);
fflush(stdout);
}
exit(0);
}
Here is the code for the server:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#define MAXCOUNT 1024
int main(int argc, char* argv[])
{
int sfd,nsfd,n,i,cn;
char buf[MAXCOUNT];
socklen_t caddrlen;
struct sockaddr_in caddr,saddr; //Structs for Client and server Address in the Internet
sfd = socket(AF_INET,SOCK_STREAM,0);
memset(&saddr,0,sizeof(saddr)); //Clear the Server address structure
saddr.sin_family = AF_INET; //Internet Address Family
saddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
saddr.sin_port = htons(5004);
bind(sfd, (struct sockaddr*) &saddr,sizeof(saddr));
listen(sfd,1);
for(; ;) {
caddrlen = sizeof(caddr);
nsfd = accept(sfd,(struct sockaddr*) &caddr,&caddrlen);
cn = recv(nsfd,buf,sizeof(buf),0);
if(cn == 0) {
exit(0);
}
buf[cn] = '\0';
send(nsfd,buf,strlen(buf),0);
}
close(nsfd);
exit(0);
}
You shouldn't call accept within the loop on the server. Move the accept before the for loop on the server and it should work how you expect.
Calling accept in the loop like that will make the server block until a new connection comes in. Your client is only opening a single connection, so the server will block on the second call to accept.
Your code is doing precisely what you asked it to do. You told it to accept a connection, receive some data from that connection, send that data back to the connection, then accept another connection. That's what it's doing. I suspect you want to move the accept call outside the for loop.
I think you required a code which servers multiple clients as well as echo message to respective clients.
so just have a look to your code again and note down modification
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#define MAXCOUNT 1024
int main(int argc, char* argv[])
{
int sfd,nsfd,n,i,cn;
char buf[MAXCOUNT];
socklen_t caddrlen;
struct sockaddr_in caddr,saddr;
//Structs for Client and server Address in the Internet
sfd = socket(AF_INET,SOCK_STREAM,0);
memset(&saddr,0,sizeof(saddr)); //Clear the Server address structure
saddr.sin_family = AF_INET; //Internet Address Family
saddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
saddr.sin_port = htons(5004);
bind(sfd, (struct sockaddr*) &saddr,sizeof(saddr));
listen(sfd,5);/*request queue size*/
while(1)
{//main loop for cuncorent server
caddrlen = sizeof(caddr);
nsfd = accept(sfd,(struct sockaddr*) &caddr,&caddrlen);
if(fork()==0)
{//only child code for serving a particular client
for(; ;) {//loop for reading and writing back msg cotineously
cn = recv(nsfd,buf,sizeof(buf),0);
if(cn == 0) {
exit(0);
}
buf[cn] = '\0';
send(nsfd,buf,strlen(buf),0);
}//serving loop ends
close(nsfd);
exit(0);
}//child code ends
}//main while loop ends
exit(0);
}