I have a socket app written in c and I am executing on linux, but when I execute the server (./server), I get the following error:
connection failed, connection refused.
Here is the code:
server.c
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include <pthread.h>
#define DEFAULT_PORT 8080
void error(char* message){
perror(message);
exit(EXIT_FAILURE);
}
void handler_client(void){
}
int main(int argc , char **argv[]){
int server_fd;
int new_socket;
int valread;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1024] = {0};
char *hello = "Hello, I'm server";
if((server_fd = socket(AF_INET, SOCK_STREAM , 0)) == 0){
error("socket failed");
}
if(setsockopt(server_fd , SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT , &opt , sizeof(opt))){
error("setsockertopt");
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(DEFAULT_PORT);
if(bind(server_fd , (struct sockaddr *)&address, sizeof(address) ) < 0){
error("bind failure");
}
if(listen(server_fd , 3) < 0){
error("listen");
}
if((new_socket = accept(server_fd , (struct sockaddr *)&address , (socklen_t *)&addrlen)) < 0){
error("accept");
}
valread = read( new_socket , buffer , 1024);
printf(" message from client : %s \n",buffer);
send(new_socket , hello , strlen(hello) , 0);
printf("Hello message sent \n");
return 0;
}
client.c
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#define DEFAULT_PORT 8080
#define BUFFER_SIZE 1024
void error(char* message){
perror(message);
exit(EXIT_FAILURE);
}
int main(int argc , char** argv){
struct sockaddr_in address;
int sock = 0;
int valread;
struct sockaddr_in serv_addr;
char message[BUFFER_SIZE] = {0};
char buffer[BUFFER_SIZE] = {0};
if((sock = socket(AF_INET , SOCK_STREAM , 0)) < 0){
error("Sockert Creation fails");
}
memset(&serv_addr , '0' , sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(DEFAULT_PORT);
if(inet_pton(AF_INET , "127.0.0.1" , &serv_addr.sin_addr) <= 0){
error("Invalid address / Address not supported");
}
if(connect(sock , (struct sockaddr *)&serv_addr , sizeof(serv_addr) ) < 0){
error("connection failed");
}
printf("enter your message : ");
fgets(message , BUFFER_SIZE-1 , stdin);
send(sock , message , strlen(message) , 0);
printf("Hello message sent\n");
valread = read(sock , buffer , BUFFER_SIZE);
printf("response from buffer : %s\n",buffer);
return 0;
}
A "connection refused" error means you are trying to connection to a server IP:port that is either:
not open for listening
has too many pending client connections in its backlog
blocked by a firewall/router/antivirus.
There is no way on the client side to differentiate which condition is causing the error. All it can do is try again later, and give up after awhile.
Since your client is trying to connection to 127.0.0.1, the client and server MUST be run on the same machine. You will not be able to connect across machine boundaries, and that includes VM boundaries between host/client systems.
That being said, I see a number of mistakes in your code, but none that are causing the connection error.
Server side:
socket() returns -1 on error, not 0.
//if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0){
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
you can't set multiple socket options at a time with setsockopt(), you must set them individually with separate calls to setsockopt().
//setsockopt(server_fd , SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt));
setsockopt(server_fd , SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
setsockopt(server_fd , SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt));
Client side:
you are filling serv_addr with '0' characters instead of 0 bytes.
//memset(&serv_addr , '0' , sizeof(serv_addr));
memset(&serv_addr, 0, sizeof(serv_addr));
On both sides, you are not doing any error handling on send(). But more importantly, you are not including the message's null terminator in the send, so the peer has no way of knowing when the end of the message is reached. TCP is a streaming transport, so you need to frame your messages in your data protocol. Send the message's length before sending the message itself. Or send a unique terminator after the message. The peer can then read the length before reading the message, or read until the terminator is reached.
Both send() and read() return how many bytes were actually sent/received, which can be (and frequently is) fewer bytes than requested. You need to call them in a loop to make sure that you send/receive everything you are expecting.
Also, read() does not return a null-terminated string, but your use of printf() expects one. Check valread for error, and only if read() was successful then pass valread to printf() as an input parameter so it knows how much data is actually in the buffer:
printf("message from client : %.*s\n", valread, buffer);
printf("response from buffer : %.*s\n", valread, buffer);
Related
I'm trying to learn UDP on C.
My goal is to send a message in console, in the client consol to the server, and sending the exact same message from the server to the client.
When I send a message from client to server, I do receive it, but the opposit is not working, and the waiting is infinite.
I don't have any problem in console.
The weird thing is that i'm using the exact same methode to send both messages.
Here's my client, Thanks to everyone helping me :)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define PORT 8080
#define BUFSIZE 4096
// Driver code
int main(int argc, char *argv[]) {
char buffer[BUFSIZE];
struct sockaddr_in servaddr, cliaddr;
int len, n;
char *adresse= argv[1];
if (argc<1){
perror("nb args not enough");
exit(EXIT_FAILURE);
}
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr(adresse);
servaddr.sin_port = htons(PORT);
// Socket()
int udp_server = socket(AF_INET, SOCK_DGRAM, 0) ;
if(udp_server<0){
perror("socket creation failed \n");
exit(EXIT_FAILURE);
}
// Bind())
int errBind = bind(udp_server, (const struct sockaddr *)&servaddr, sizeof(servaddr));
if(errBind<0){
perror("errBind \n" );
exit(EXIT_FAILURE);
}
// recvfrom()
n = recvfrom(udp_server, (char *)buffer, BUFSIZE,0, ( struct sockaddr *) &cliaddr,&len);
if (n<0){
perror("recvfrom error\n" );
exit(EXIT_FAILURE);
}
buffer[n] = '\0';
printf("CLIENT: %s\n", buffer);
char *message ="caca";
sendto(udp_server, (const char *)message, strlen(message),
0, (const struct sockaddr *) &cliaddr,
len);
close(udp_server);
//////////////////////////This part below is never reached
printf("end");
return 0;
}
Also here's my server:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define PORT 8080
#define BUFSIZE 4096
// Driver code
int main(int argc, char *argv[]) {
char buffer[BUFSIZE];
// char *message = "AAAAAAAAAAAAAAAAAA";
struct sockaddr_in servaddr, cliaddr;
int len, n;
char *adresse= argv[1];
if (argc<1){
perror("nombre d'arguments insuffisents, veuillez entrer :\n ./serveur port_serveur \n");
exit(EXIT_FAILURE);
}
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr(adresse);
// servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_port = htons(PORT);
// Socket()
int udp_server = socket(AF_INET, SOCK_DGRAM, 0) ;
if(udp_server<0){
perror("socket creation failed \n");
exit(EXIT_FAILURE);
}
// Bind())
int errBind = bind(udp_server, (const struct sockaddr *)&servaddr, sizeof(servaddr));
if(errBind<0){
perror("errBind \n" );
exit(EXIT_FAILURE);
}
// recvfrom()
n = recvfrom(udp_server, (char *)buffer, BUFSIZE,0, ( struct sockaddr *) &cliaddr,&len);
if (n<0){
perror("recvfrom error\n" );
exit(EXIT_FAILURE);
}
buffer[n] = '\0';
printf("CLIENT: %s\n", buffer);
int l = sendto(udp_server, (const char *)buffer, strlen(buffer),
0, (const struct sockaddr *) &servaddr,
sizeof(servaddr));
close(udp_server);
printf("end");
//////////////// This is reached
return 0;
}
There are several issues. The main issue is that both the client and server first tries to receive, then send. Thus they cannot both receive the message from the other party. Also, the client need not explicitly bind the socket.
In principle, the client must know the server address, but the server does not know the client address. Hence, the flow of communication must be that the client first sends a message to the server which will make the client known to the server. The server can then send a message to the address of the client.
In summary, the server should:
Create socket
Bind socket
Wait for message (recvfrom())
Send message to sender of the received message (sendto())
Close socket
The client should:
Create socket
Send message to the server (sendto())
Wait for message (recvfrom())
Close socket
I have a simple websocket program where a server and client exchange a message and then exit, taken from a geeks for geeks tutorial:
https://www.geeksforgeeks.org/socket-programming-cc/
server.c:
// Server side C/C++ program to demonstrate Socket programming
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#define PORT 8080
int main(int argc, char const *argv[])
{
int server_fd, new_socket, valread;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1024] = {0};
char *hello = "Hello from server";
// Creating socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
perror("socket failed");
exit(EXIT_FAILURE);
}
// Forcefully attaching socket to the port 8080
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
&opt, sizeof(opt)))
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( PORT );
// Forcefully attaching socket to the port 8080
if (bind(server_fd, (struct sockaddr *)&address,
sizeof(address))<0)
{
perror("bind failed");
exit(EXIT_FAILURE);
}
if (listen(server_fd, 3) < 0)
{
perror("listen");
exit(EXIT_FAILURE);
}
if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
(socklen_t*)&addrlen))<0)
{
perror("accept");
exit(EXIT_FAILURE);
}
valread = read( new_socket , buffer, 1024);
printf("%s\n",buffer );
send(new_socket , hello , strlen(hello) , 0 );
printf("Hello message sent\n");
return 0;
}
client.c:
// Client side C/C++ program to demonstrate Socket programming
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#define PORT 8080
int main(int argc, char const *argv[])
{
printf("$");
int sock = 0, valread;
struct sockaddr_in serv_addr;
char *hello = "Hello from client";
char buffer[1024] = {0};
printf("#");
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Socket creation error \n");
return -1;
}
printf("#");
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
// Convert IPv4 and IPv6 addresses from text to binary form
//CURRENT IP IS RPI4 IP
if(inet_pton(AF_INET, "192.168.0.12", &serv_addr.sin_addr)<=0)
{
printf("\nInvalid address/ Address not supported \n");
return -1;
}
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\nConnection Failed \n");
return -1;
}
printf("!\n");
send(sock , hello , strlen(hello) , 0 );
printf("Hello message sent\n");
valread = read( sock , buffer, 1024);
printf("%s\n",buffer );
return 0;
}
My raspberry pi 4 is the server and my raspberry pi 3 is the client. On my normal home wifi network this program executes exactly as expected.
However I have turned my RPI4 into a standalone wifi access point using this tutorial: https://www.raspberrypi.org/documentation/configuration/wireless/access-point-routed.md
When I connect the RPI3 client to the RPI4 network, and run the server and then the client program it hangs and seems like it isn't even running the first line of code and printing the "$", (this may not be the case as the assembler may move the first print statement somewhere else in execution).
I'm assuming this isn't a problem with my either of my programs but a problem with either the RPI4 access point or the RPI3's connection to the access point, but I know very little about networking. Can someone help me troubleshoot and pinpoint what the problem is?
Help me to correct this program I want to create a server that can run indefinitely and can serve many clients and for that, I am using a select system call for UDP (User Datagram Protocol) application.
My issue is that this code is running for multiple clients in a different session that means after running for one client it stops and again when I start the server again then it can serve another client also.
I want my code to work indefinitely in one session only and serve as many clients as I want.
Server Code:-
'''
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define port1 8080
#define MAXN 1024
#define TRUE 1
int main(){
int sockfd,sockfd1;
struct sockaddr_in servaddr,cliaddr;
char buffer[MAXN];
char buff[MAXN];
int max_clients=2,valread,new_socket;
char *hello = "Hello Client";
char *message = "hiiii Server";
struct timeval timeout;
timeout.tv_sec = 20;
timeout.tv_usec = 0;
//create socket 2
sockfd = socket(AF_INET, SOCK_DGRAM,0);
if(sockfd<0){
perror("Error Creating Socket0");
exit(1);
}
//memset(&servaddr, 0, sizeof(servaddr));
//memset(&cliaddr, 0, sizeof(cliaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(port1);
servaddr.sin_addr.s_addr = INADDR_ANY;
if(bind(sockfd, (const *)&servaddr, sizeof(servaddr))<0){
perror("Error in binding0 ");
exit(1);
}
//Use Select......
//I have created 2 socket having file deescriptor sockfd and sockfd1
int s;
int client_socket[2]={0,0};
fd_set readfds;
while(){
FD_ZERO(&readfds);
FD_SET(sockfd,&readfds);
//Let's say sockfd is max_fd
int max_fd = sockfd,sd,activity;
for(int i=0;i<2;i++){
sd = client_socket[i];
if(sd>0){
FD_SET(sd,&readfds);
}
if(sd>max_fd)
max_fd = sd;
}
activity = select( max_fd + 1 , &readfds , NULL , NULL , &timeout);
if ((activity < 0))
{
printf("select error");
}
int addrlen = sizeof(servaddr);
//If something happened on the master socket ,
//then its an incoming connection
if (FD_ISSET(sockfd, &readfds))
{
//inform user of socket number - used in send and receive commands
printf("New connection , socket fd is %d , ip is : %s , port : %d\n " , new_socket , inet_ntoa(servaddr.sin_addr) , ntohs
(servaddr.sin_port));
//send new connection greeting message
if( send(new_socket, message, strlen(message), 0) != strlen(message) )
{
perror("send");
}
puts("Welcome message sent successfully");
//add new socket to array of sockets
for (int i = 0; i < max_clients; i++)
{
//if position is empty
if( client_socket[i] == 0 )
{
client_socket[i] = new_socket;
printf("Adding to list of sockets as %d\n" , i);
break;
}
}
}
//else its some IO operation on some other socket
for (int i = 0; i < max_clients; i++)
{
sd = client_socket[i];
if (FD_ISSET( sd , &readfds))
{
//Check if it was for closing , and also read the
//incoming message
if ((valread = read( sd , buffer, 1024)) == 0)
{
//Somebody disconnected , get his details and print
getpeername(sd , (struct sockaddr*)&servaddr , \
(socklen_t*)&addrlen);
printf("Host disconnected , ip %s , port %d \n" ,
inet_ntoa(servaddr.sin_addr) , ntohs(servaddr.sin_port));
//Close the socket and mark as 0 in list for reuse
//close( sd );
client_socket[i] = 0;
}
//Echo back the message that came in
else
{
//set the string terminating NULL byte on the end
//of the data read
buffer[valread] = '\0';
send(sd , buffer , strlen(buffer) , 0 );
}
}
}
}
return 0;
}
'''
This is one of the Client Code and this code is running :-
'''
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define PORT 8080
#define MAXN 1024
// Driver code
int main() {
int sockfd;
char buffer[MAXN];
char *hello = "Hello from Multipleclient";
struct sockaddr_in servaddr;
// Creating socket file descriptor
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror("Error in socket creation");
exit(1);
}
memset(&servaddr, 0, sizeof(servaddr));
// Filling server information
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT);
servaddr.sin_addr.s_addr = INADDR_ANY;
int n, len;
sendto(sockfd, (const char *)hello, strlen(hello),
MSG_CONFIRM, (const struct sockaddr *) &servaddr,
sizeof(servaddr));
printf("Hello message sent.\n");
n = recvfrom(sockfd, (char *)buffer, MAXN,
MSG_WAITALL, (struct sockaddr *) &servaddr,
&len);
buffer[n] = '\0';
printf("Server : %s\n", buffer);
close(sockfd);
return 0;
}
Some minor things to start with:
In the client code, you do not initialize len before passing it to recvfrom. Also, it is of the wrong type (int instead of socklen_t). This can be corrected by defining len as socklen_t len = sizeof(servaddr); However, since you do not use the length or address anywhere, you can just pass in NULL for both. Also, UDP does not support MSG_WAITALL, so pass 0 instead for the flags. recvfrom(sockfd, (char *)buffer, MAXN, 0, NULL, NULL).
In the client code, you fill in the server IP address as IPADDR_ANY, i.e. 0.0.0.0, which is only valid when calling bind. You are calling sendto. When specifying a destination address, you probably want IPADDR_LOOPBACK for the local computer.
In the server code, the main while() loop is missing a condition inside the parenthesis, so the code does not even compile. You probably want while(1) for an infinite loop.
In the server code, in the call to bind, you are casting to the wrong type. (const *) means (const int *), but you want (const struct sockaddr *).
The biggest problem:
Based on the comments and code in the server code, you seem to think that UDP communication has persistent connections, and try to save client_socket values for these. However, UDP does not have persistent connection. There is no such thing as a client socket in this context. select does not tell you that a new "connection" is ready. Instead, it tells you that data has been received on your one and only UDP socket (sockfd). This is entirely unlike TCP, where you accept a connection that lasts until one side terminates it.
From the comments in the server code, it seems that you intend for clients to have persistent state in the server, at least enough to be recognized when they send more datagrams (otherwise they would always get the welcome message).
A possible way to make this work is the following:
// create and bind a UDP socket as you already do;
// initialize and empty list of clients;
while(1) {
struct sockaddr_in cliaddr;
socklen_t cliaddr_len = sizeof(cliaddr);
recvfrom(sockfd, buffer, bufferlen, /*flags*/ 0, (struct sockaddr *)&cliaddr, &cliaddr_len);
// check whether cliaddr is in your list;
if (!is_in_list) {
// this is a new client
// add to list of clients;
// send welcome message;
}
// do something else, maybe echo back the buffer contents;
}
You will notice that the code does not actually use select anymore. select is unnecessary if you have nothing to do while waiting, and you only listen to one socket. If you are doing other stuff not shown in the question, you can add the select back at the top of the infinite loop, and only handle the UDP socket if sockfd is set in the readfds from select.
Also note that the client cannot actually receive answers from the server, since there is no persistent connection, and the client has not passed any socket to bind. And also note that UDP messages may get lost without warning, and you should make sure your code can deal with that. It seems that this client-server-strategy would be easier to implement using TCP.
As a side note, it is strongly recommended to enable warnings in your compiler. That would have caught the wrong type for the address length variables, as well as told you that new_socket is used but never set. It is polite to fix all warnings before posting a question, unless of course the question is about the warning.
I want to make a server-client programm.The first thing i can't find is to make the server never shut down and accept each client.I put a while(1) on my server to run but after 3 connections to one client my server stops accepting other connections and i delete this while.I cant find how to build this think.Also i want to create TCP/IP socket so am i making the socket with the right way?
Im working on ubuntu at Visual Studio Code.
Server:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#define PORT 8080
int main(int argc,char* argv[]){
int server_fd, new_socket, valread;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char *hello = "Hello from server";
while(1){
char buffer[1024] = {0};
printf("Server\n");
// Creating socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
// Forcefully attaching socket to the port 8080
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,&opt,
sizeof(opt))) {
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( PORT );
// Forcefully attaching socket to the port 8080
if (bind(server_fd, (struct sockaddr *)&address,sizeof(address))<0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
if (listen(server_fd, 1) < 0) {
perror("listen");
exit(EXIT_FAILURE);
}
printf("Listening...\n");
if ((new_socket = accept(server_fd, (struct sockaddr *)&address,(socklen_t*)&addrlen))<0) {
perror("accept");
exit(EXIT_FAILURE);
}
valread = read( new_socket , buffer, 1024);
printf("%s\n",buffer );
send(new_socket , hello , strlen(hello) , 0 );
printf("Hello message sent\n");
}
return 0;
}
My client so far:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#define PORT 8080
int main(int argc,char* argv[]){
char* command = (char*) malloc(15*sizeof(char));
int sock = 0, valread;
struct sockaddr_in serv_addr;
char *hello = "Hello from client";
char buffer[1024] = {0};
printf("Client\n");
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0){
printf("\n Socket creation error \n");
return -1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
// Convert IPv4 and IPv6 addresses from text to binary form
if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0) {
printf("\nInvalid address/ Address not supported \n");
return -1;
}
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
printf("\nConnection Failed \n");
return -1;
}
send(sock , hello , strlen(hello) , 0 );
printf("Hello message sent\n");
valread = read( sock , buffer, 1024);
printf("%s\n",buffer );
return 0;
}
You have to put the loop only around the code, which accepts the clients. The server socket itself is only created once.
// Creation of server socket(), bind(), listen()
while (1) {
if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
(socklen_t*)&addrlen)) < 0) {
perror("accept");
exit(EXIT_FAILURE);
}
valread = read( new_socket , buffer, 1024);
printf("%s\n",buffer );
send(new_socket , hello , strlen(hello) , 0 );
printf("Hello message sent\n");
}
Furthermore, you should close the client socket at the end of the while block after the communication is finished (i.e. after the printf("Hello message sent\n");:
close(new_socket);
And note, that the clients are served serially this way. They can connect concurrently, but only one client is served at a time. If you need concurrent handling, you can for example fork() several processes, each handling one client, or handle multiple clients in one thread using poll() or select().
i am just starting to learn how to code socket but having problem i can't solve.
so i was trying to create a telnet client and i have succeeded to receive the first message from the server but after this receive line, my program kind of stuck and won't do anything else. not even a simple printf line.
thanks in advance,
Ricky
here's the code:
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
void error_msg(char msg[256]){
printf("error at %s\n", msg);
}
void main(){
struct sockaddr_in serv_addr;
char buffer[2048], server_reply[2048];
printf("trying to connect to []...\n");
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd<0) error_msg("socket");
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr("192.168.0.1");
serv_addr.sin_port = htons(23);
int conn = connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr));
if(conn<0) error_msg("connect");
printf("connected to server\n");
bzero(server_reply, 2048);
bzero(buffer, 2048);
while(1){
int n_recv = recv(sockfd , server_reply , sizeof(server_reply) , 0);
if(n_recv > 0){
printf("%s", server_reply);
sleep(1);
scanf("%s" , buffer);
int n_send = send(sockfd , buffer , sizeof(buffer), 0);
if(n_send < 0) printf("send error, server is not responding...\n");
}
if(n_recv < 0) printf("recv error, server is not responding...\n");
}
close(sockfd);
}
Without knowing exactly what the return value is, it seems likely the remote side has closed the connection:
http://linux.die.net/man/2/recv
The return value will be 0 when the peer has performed an orderly shutdown.
Look at my comment on your question and post that data and I should be able to help more.