Hey guys I want to send a message of the current date from the server to a client in C.
So I would use a command like this for the client;
Terminal
telnet localhost PORT
What should be the command to send the actual message?
int main(int argc, char *argv[])
{
int socket_desc, client_sock, c, read_size;
struct sockaddr_in server, client;
char client_message[2000];
time_t t = time(NULL);
struct tm tm = *localtime(&t);
socket_desc = socket(AF_INET, SOCK_STREAM, 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(PORT);
if (bind(socket_desc, (struct sockaddr *)&server, sizeof(server)) < 0)
{
perror("bind failed. Error");
return 1;
}
listen(socket_desc, 3);
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t *)&c);
if (client_sock < 0)
{
perror("accept failed");
return 1;
}
puts("Connection accepted");
////////////////////////////////////////////////////
//the actual message here
////////////////////////////////////////////////////
close(socket_desc);
return 0;
}
I made the following addiction and it worked
Is this a proper solution? I don't know how to use send() properly yet.
pid_t child_pid = fork();
if (child_pid == 0)
{
snprintf(client_message, sizeof(client_message), "%s", ctime(&tick));
write(client_sock, client_message, strlen(client_message));
shutdown(client_sock, SHUT_RDWR);
while (read(client_sock, client_message, sizeof(client_message) > 0))
close(client_sock);
}
else if (child_pid > 0)
{
// parent
close(client_sock);
}
else
{
// a fork error occurred, handle and remember to close(connfd)
}
Related
I'm trying to make a simple multi-thread server in C, and I would like to make a queue for clients, so no one drops connection.
But I have no idea what to do and where to start.
Anyone can help? Any advices would be appreciated :)
and I had to remove the thread function code because code was too long that this question won't post.
int main(int argc, char const *argv[])
{
int server_fd, new_socket; //long valread;
struct sockaddr_in address;
int addrlen = sizeof(address);
pthread_t tid[1024];
int i = 0; // index for tid array
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
perror("In socket");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( PORT );
memset(address.sin_zero, '\0', sizeof address.sin_zero);
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address))<0)
{
perror("In bind");
exit(EXIT_FAILURE);
}
if (listen(server_fd, 10) < 0)
{
perror("In listen");
exit(EXIT_FAILURE);
}
while(1)
{
printf("\n+++++++ Waiting for new connection ++++++++\n\n");
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen))<0)
{
perror("In accept");
exit(EXIT_FAILURE);
}
if( pthread_create(&tid[i++], NULL, thread, &new_socket) != 0 )
printf("Failed to create thread\n");
if( i >= 1024 )
i = 0;
}
return 0;
}
I am trying to implement a server which accepts 2 connections one after another each of them sending data. My client-side can connect and fwrite successfully whereas my server-side connects successfully but fails to recv() anything. I have tried many things on the net but I could not resolve this. Why would recv() fail in this code after succesfully accepting and connecting on the socket?
Code of Server part —— Successful on accept() but fail on recv()
char** get_host_ip(){
char** arr = malloc(3* sizeof(char*));
int x;
for(x=0; x<3;x++){
arr[x] = malloc(256 *sizeof(char));
}
int socket_desc , client_sock , c , *new_sock;
struct sockaddr_in server , client;
fd_set fdset;
struct timeval tv;
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
//fcntl(socket_desc, F_SETFL, O_NONBLOCK);
if (socket_desc == -1)
{
printf("Could not create socket");
}
puts("Socket created");
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 8888 );
int reuse = 1;
if (setsockopt(socket_desc, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int)) < 0){
perror("setsockopt(SO_REUSEADDR) failed");
}
if(setsockopt(socket_desc, SOL_SOCKET, SO_REUSEPORT, &reuse, sizeof(int)) < 0){
perror("setsockopt(SO_REUSEPORT) failed");
}
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
//print the error message
perror("bind failed. Error");
char* err = "Error on binding\r\n";
printf("%s\r\n",err);
}
puts("bind done");
//Listen
listen(socket_desc , 20);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
int k;
for(k=0; k<2; k++){
client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
if(client_sock < 0){
puts("Accept failed\r\n");
exit(0);
}
else{
puts("Accept succeeded");
}
if(k == 0) {
char* host_ip = inet_ntoa(client.sin_addr);
printf("IP address is: %s\n", inet_ntoa(client.sin_addr));
printf("port is: %d\n", (int) ntohs(client.sin_port));
strcpy(arr[k],host_ip);
int read_size = 0;
char readBuf[256];
if((read_size = recv(client_sock , readBuf , 256 , 0)) > 0){
printf("readBuf: %s\r\n",readBuf);
strcpy(arr[k+1],readBuf);
memset(readBuf,0,256);
}
else{
printf("Receive has failed.. read_size: %d\r\n",read_size);
}
}
else {
int read_size;
char readBuf[256];
if((read_size = recv(client_sock , readBuf , 256 , 0)) > 0){
printf("readBuf: %s\r\n",readBuf);
strcpy(arr[k+2],readBuf);
memset(readBuf,0,256);
}
else{
printf("Receive has failed.. read_size: %d\r\n",read_size);
}
}
}
close(client_sock);
close(socket_desc);
return arr;
}
Client part —— connect() and fwrite() successful
void give_envi(char* env_var) {
printf("The environment variable sent: %s\r\n",env_var);
int receive_no = 1;
int sock;
struct sockaddr_in server;
//Create socket
sock = socket(AF_INET , SOCK_STREAM , 0);
if (sock == -1)
{
printf("Could not create socket");
}
//puts("Socket created");
//char host_ip[20];
//strcpy(host_ip,getenv("HOST_IP"));
server.sin_addr.s_addr = inet_addr("127.0.0.1"); //PROVIDE THE IP OF THE TARGET TO SEND YOUR DATA.
server.sin_family = AF_INET;
server.sin_port = htons( 8888 );
int reuse = 1;
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int)) < 0){
perror("setsockopt(SO_REUSEADDR) failed");
}
if(setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &reuse, sizeof(int)) < 0){
perror("setsockopt(SO_REUSEPORT) failed");
}
//Connect to remote server
if ( connect(sock , (struct sockaddr *)&server , sizeof(server)) > -1) {
puts("Connection established!\r\n");
}
else{
puts("Connection failed\r\n");
}
FILE * file = fdopen(sock, "w");
if(fwrite (env_var ,sizeof(char), strlen(env_var), file) == strlen(env_var)){
printf("fwrite() SUCCESS\r\n");
}
else{
printf("FAILED on fwrite()\r\n");
}
close(sock);
}
I am fairly new to socket programming. I saw a tutorial and tried implementing the programs in my Linux machine. The codes are :
CLIENT :
int main() {
char buf[256] = "In client";
// create the socket
int sock;
sock = socket(AF_INET, SOCK_STREAM, 0);
//setup an address
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = INADDR_ANY;
server_address.sin_port = htons(9002);
int status = connect(sock, (struct sockaddr *) &server_address, sizeof(server_address));
if(status == -1)
{
printf("There Was an error!");
}
recv(sock, buf, sizeof(buf), 0);
printf("\n %s \n", buf);
close(sock);
return 0;
}
SERVER:
int main() {
char server_message[256] = "You have reached the server!";
// create the server socket
int server_socket;
server_socket = socket(AF_INET, SOCK_STREAM, 0);
// define the server address
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(9002);
server_address.sin_addr.s_addr = INADDR_ANY;
// bind the socket to our specified IP and port
bind(server_socket, (struct sockaddr*) &server_address, sizeof(server_address));
listen(server_socket, 5);
int client_socket;
client_socket = accept(server_socket, NULL, NULL);
// send the message
send(client_socket, server_message, sizeof(server_message), 0);
// close the socket
close(server_socket);
return 0;
}
The code is self-explanatory. When I run the server and then the client, for the first time, it works. But when I do it again, just after the previous one, the Client gives the message - There Was an error!, that means the connection is not happening.
Can anyone help why is this occurring?
Thanks in advance!
You should be checking for errors for all system calls in your server. I'm guessing that your bind is failing, because the port is "already in use". The reason for this is that the connection from the previous instance of the server lingers for a while in the operating system's connection table.
You want to use setsockopt with SO_REUSEADDR to avoid the bind failure. Specifically, add this prior to the bind call.
int reuse = 1;
if (setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0)
perror("setsockopt(SO_REUSEADDR) failed");
(And do check errors. Makes debugging these kinds of things much easier if you know when something fails. Also, use perror or strerror(errno) in order to find out exactly why it failed -- not just that it failed.)
Check out my whole code here and see how it runs.
This is the server
int main(){
SOCKET s, newsocket;
struct sockaddr_in server, client;
int receiving;
char clientMessage[2000], *message;
if((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET){
printf("socker error at %d", GetLastError());
}else{
puts("socket created");
}
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(8080);
if(bind(s, (struct sockaddr*)&server, sizeof(server)) < 0){
printf("err at binding %d", GetLastError());
}else{
puts("binded.");
}
listen(s, 3);
puts("listening to connections...");
int c = sizeof(struct sockaddr_in);
while((newsocket = accept(s, (struct sockaddr*)&client, &c)) != INVALID_SOCKET){
puts("connection accepted");
//send
message="hello client";
send(newsocket, message, strlen(message), 0);
recv(newsocket, clientMessage, 50, 0);
puts(clientMessage);
}
puts("waiting for a machine");
if(newsocket == INVALID_SOCKET){
printf("newsocket invalid at %d", GetLastError());
}
getchar();
closesocket(s);
WSACleanup();
}
This is the client
int main(){
SOCKET s;
struct sockaddr_in server;
if((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET){
printf("socket error At %d", GetLastError());
}else{
puts("socket initialised");
}
server.sin_port = htons(8080);
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr("176.40.201.72");
printf("server values are defined.. \n");
printf("connecting..\n");
if(connect(s, (struct sockaddr*)&server, sizeof(server)) < 0){
printf("connection error %d" , GetLastError());
}else{
puts("connected");
}
return 0;
}
I am new to working with TCP sockets and I do not understand the errors I am getting when running my programs. I have two programs that when run simultaneous I would like to be able to pass messages between. The initial message gets through but then when trying to return another message I get two errors. When I run my first program the output is:
Input Message: hello
Waiting for incoming connections...
Connection accepted
Message Sent
Connection error: Transport endpoint is already connected
Now running the other program simultaneously gives:
Input Message: Hello Back
Connected
Message received
hello
Bind error: Cannot assign requested address
If anyone could explain these "cannot assign requested address" and " Transport endpoint is already connected" errors I would greatly appreciate it!! Thanks!
The first program is:
int main(int argc, char *argv[]) {
int socket_info, new_socket;
struct sockaddr_in server, client;
char message[100];
char incoming_message[100];
printf("Input Message: ");
fgets(message, 100, stdin);
//create socket
socket_info = socket(AF_INET, SOCK_STREAM, 0);
if (socket_info == -1) {
printf("Could not create socket");
}
//assign values
server.sin_addr.s_addr = INADDR_ANY;
server.sin_family = AF_INET;
server.sin_port = htons( 1100 );
int y=1;
if(setsockopt(socket_info, SOL_SOCKET, SO_REUSEADDR, (char*)&y, sizeof(y)) == -1) {
perror("set reuseaddr");
return -1;
}
//binds socket
if (bind(socket_info, (struct sockaddr *)&server, sizeof(server)) < 0) {
perror("Bind error");
return 1;
}
//listen
listen(socket_info , 5);
//waiting for connection
puts("Waiting for incoming connections...");
int c = sizeof(struct sockaddr_in);
//accept connection
new_socket = accept(socket_info, (struct sockaddr *)&client, (socklen_t*)&c);
if (new_socket < 0){
perror("accept failed");
return 1;
}
puts("Connection accepted");
//send message
if( send(new_socket , message , strlen(message) , 0) < 0) {
perror("Send failed");
return 1;
}
puts("Message Sent");
//connects
if (connect(socket_info, (struct sockaddr *)&server, sizeof(server)) < 0) {
perror("Connection error");
return 1;
}
puts("Connected");
//Receive an incoming message
if( recv(socket_info, incoming_message , sizeof(incoming_message) , 0) < 0) {
perror("Received failed");
return 1;
}
puts("Message received");
incoming_message[strlen(incoming_message)-1]=0;
puts(incoming_message);
close(socket_info);
}
The second program is:
int main(int argc, char *argv[]) {
int socket_info, new_socket;
struct sockaddr_in server, client;
char incoming_message[100];
char message[100];
printf("Input Message: ");
fgets(message, 100, stdin);
//create socket
socket_info = socket(AF_INET, SOCK_STREAM, 0);
if (socket_info == -1) {
printf("Could not create socket");
}
//assign values
server.sin_addr.s_addr = inet_addr("172.21.8.178");
server.sin_family = AF_INET;
server.sin_port = htons( 1100 );
//connects
if (connect(socket_info, (struct sockaddr *)&server, sizeof(server)) < 0) {
perror("Connection error");
return 1;
}
puts("Connected");
//Receive an incoming message
if( recv(socket_info, incoming_message , sizeof(incoming_message) , 0) < 0) {
perror("Received failed");
return 1;
}
puts("Message received");
incoming_message[strlen(incoming_message)-1]=0;
puts(incoming_message);
int y=1;
if(setsockopt(socket_info, SOL_SOCKET, SO_REUSEADDR, (char*)&y, sizeof(y)) == -1) {
perror("set reuseaddr");
return -1;
}
//binds socket
if (bind(socket_info, (struct sockaddr *)&server, sizeof(server)) < 0) {
perror("Bind error");
return 1;
}
//listen
listen(socket_info , 5);
//waiting for connection
puts("Waiting for incoming connections...");
int c = sizeof(struct sockaddr_in);
//accept connection
new_socket = accept(socket_info, (struct sockaddr *)&client, (socklen_t*)&c);
if (new_socket < 0){
perror("accept failed");
return 1;
}
puts("Connection accepted");
//send message
if( send(new_socket , message , strlen(message) , 0) < 0) {
perror("Send failed");
return 1;
}
puts("Message Sent");
close(socket_info);
}
if (connect(socket_info, (struct sockaddr *)&server, sizeof(server)) < 0) {
perror("Connection error");
return 1;
}
Connection error: Transport endpoint is already connected
I asssume socket_info above should be new_socket?
You can't connect a listening socket.
You don't need to connect the listening socket. You have just accepted a socket from a client connection. You should do your I/O to that client with that socket.
In your second program:
if(setsockopt(socket_info, SOL_SOCKET, SO_REUSEADDR, (char*)&y, sizeof(y)) == -1) {
perror("set reuseaddr");
return -1;
}
This is futile. The socket is already bound, implicitly, via the connect() call preceding.
//binds socket
if (bind(socket_info, (struct sockaddr *)&server, sizeof(server)) < 0) {
perror("Bind error");
return 1;
}
Bind error: Cannot assign requested address
You can't bind a socket that is already connected.
Nor can you bind a socket to a remote address.
Nor can you listen on a connected socket.
Nor can you accept from it. You don't need to bind, or listen, or accept from it. You are already connected to the peer.
In short your code doesn't make any sense whatsoever. You need to find a proper tutorial and study it.
incoming_message[strlen(incoming_message)-1] = 0;
This makes even less sense. Here you are searching for a trailing null byte (which may not even be there) and replacing the byte before it by ... a null byte. Why?
I am writing a simple client and server program in C. I am able to send date from client to server. But, I am not able to send acknowledge from server to client.
/*******************udpserver.c*****************/
int main(int argc, char *argv[])
{
/* Variable and structure definitions. */
int sd, rc;
struct sockaddr_in serveraddr, clientaddr;
clientaddrlen = sizeof(clientaddr);
int serveraddrlen = sizeof(serveraddr);
char buffer[100];
char *bufptr = buffer;
int buflen = sizeof(buffer);
if((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("UDP server - socket() error");
exit(-1);
}
printf("UDP server - socket() is OK\n");
memset(&serveraddr, 0x00, serveraddrlen);
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(0);
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
if((rc = bind(sd, (struct sockaddr *)&serveraddr, serveraddrlen)) < 0) {
perror("UDP server - bind() error");
close(sd);
exit(-1);
}
int addr_len = sizeof(serveraddr);
if (getsockname(sd, (struct sockaddr *) &serveraddr, &addr_len)<0) {
perror("Error getting socket name.\n");
return -1;
}
printf("Using IP %s and port %d\n", inet_ntoa(serveraddr.sin_addr), ntohs(serveraddr.sin_port));
printf("UDP server - Listening...\n");
rc = recvfrom(sd, bufptr, buflen, 0, (struct sockaddr *)&clientaddr, &clientaddrlen);
if(rc < 0) {
perror("UDP Server - recvfrom() error");
close(sd);
exit(-1);
}
printf("UDP Server received the following:\n \"%s\" message\n", bufptr);
printf("UDP Server replying to the UDP client...\n");
rc = sendto(sd, bufptr, buflen, 0, (struct sockaddr *)&clientaddr, clientaddrlen);
if(rc < 0) {
perror("UDP server - sendto() error");
close(sd);
exit(-1);
}
printf("UDP Server - sendto() is OK...\n");
close(sd);
exit(0);
}
My UDPClient program:
/****************udpclient.c********************/
int main(int argc, char *argv[])
{
/* Variable and structure definitions. */
int sd, rc;
struct sockaddr_in serveraddr, clientaddr;
int serveraddrlen = sizeof(serveraddr);
char server[255];
char buffer[100];
char *bufptr = buffer;
int buflen = sizeof(buffer);
struct hostent *hostp;
memset(buffer, 0x00, sizeof(buffer));
/* 36 characters + terminating NULL */
memcpy(buffer, "Hello! A client request message lol!", 37);
if((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("UDP Client - socket() error");
exit(-1);
}
else
printf("UDP Client - socket() is OK!\n");
if(argc != 3) {
/*Use default hostname or IP*/
printf("UDP Client - Usage <Server hostname or IP>\n");
exit(0);
}
memset(&serveraddr, 0x00, sizeof(struct sockaddr_in));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(atoi(argv[2]));
hostp = gethostbyname(argv[1]);
if(hostp == (struct hostent *)NULL) {
printf("HOST NOT FOUND --> ");
printf("h_errno = %d\n", h_errno);
exit(-1);
}
else {
printf("UDP Client - gethostname() of the server is OK... \n");
printf("Connected to UDP server\n");
}
memcpy(&serveraddr.sin_addr, hostp->h_addr, sizeof(serveraddr.sin_addr));
rc = sendto(sd, bufptr, buflen, 0, (struct sockaddr *)&serveraddr, sizeof(serveraddr));
if(rc < 0) {
perror("UDP Client - sendto() error");
close(sd);
exit(-1);
}
else
printf("UDP Client - sendto() is OK!\n");
printf("Waiting a reply from UDP server...\n");
rc = recvfrom(sd, bufptr, buflen, 0, (struct sockaddr *)&serveraddr, &serveraddrlen);
if(rc < 0) {
perror("UDP Client - recvfrom() error");
close(sd);
exit(-1);
} else {
printf("UDP client received the following: \"%s\" message\n", bufptr);
}
close(sd);
exit(0);
}
When running the two programs, I am getting the following output:
UdpServer:
$ ./UdpServer
UDP server - socket() is OK
Using IP 0.0.0.0 and port 49932
UDP server - Listening...
UDP Server received the following:
"Hello! A client request message lol!" message
UDP Server replying to the UDP client...
UDP Server - sendto() is OK...
UdpClient:
$ ./UdpClient MyPC 49932
UDP Client - socket() is OK!
UDP Client - gethostname() of the server is OK...
Connected to UDP server
UDP Client - sendto() is OK!
Waiting a reply from UDP server...
UdpClient program is stuck at this point. Could anyone please explain what the problem is?
You might like to use select() to make the process wait until data is avaibale for reading:
...
{
fd_set rfds;
int retval;
FD_ZERO(&rfds);
FD_SET(sd, &rfds);
retval = select(sd+1, &rfds, NULL, NULL, NULL);
if (retval == -1)
perror("select()");
else
printf("Data is available for reading now.\n");
...
}
...
If the server and client are running on the same machine, give
$ ./UdpClient localhost 49932
instead of
$ ./UdpClient MyPC 49932
else
$ ./UdpClient <server-IP-address> 49932
Also in the server code,
clientaddrlen = sizeof(clientaddr);
should be
int clientaddrlen = sizeof(clientaddr);
But I guess that's just a copy-paste mistake.