he server is accepting the clients, but no message is received. Here is my code for server:
Server:
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<string.h>
#include<stdbool.h>
#include<sys/select.h>
#include<errno.h>
//Socket Creation
int socketFile(){
int Socket = socket(AF_INET, SOCK_STREAM, 0);
if(Socket == -1){
perror("Socket Error\n");
exit(1);
}
else
printf("Successfullly Connected to Socket: %d\n",Socket);
return Socket;
}
int bindFile(int Socket, const struct sockaddr * receiver, int len){
int Bind = bind(Socket, receiver, len);
if(Bind == -1){
perror("Bind Error\n");
exit(1);
}
else
printf("Successfullly Connected with Bind number: %d\n", Bind);
}
int listenFile(int Socket, int n){
int listen1 = listen(Socket, n);
if(listen1 == -1){
perror("listen Error\n");
exit(1);
}
else
printf("Successfully Connected with no Listen Error\n");
}
int acceptFile(int Socket, struct sockaddr * receiver, socklen_t addrlen){
int accept1 = accept(Socket, (struct sockaddr *)&receiver, &addrlen);
if(accept1 == -1){
perror("accept Error\n");
exit(1);
}
else
printf("Successfully Accepted with Data Socket number: %d\n", accept1);
}
void clearBuffer(char* b, int len) {
int i;
for (i = 0; i < len; i++)
b[i] = '\0';
sleep(0.1);
}
int main(int abcd, char *args[]) {
//Socket
int Socket = socketFile();
//Struct for Receiver
struct sockaddr_in receiver, sender;
receiver.sin_family = AF_INET;
receiver.sin_port = htons(atoi(args[1]));
receiver.sin_addr.s_addr = inet_addr("127.0.0.1");
int addrlength = sizeof(sender);
socklen_t senderLength;
//Bind
int Bind = bindFile(Socket, (const struct sockaddr *)&receiver, addrlength);
//Listen
int Listen = listenFile(Socket, 5);
char buffer[21];
clearBuffer(buffer, 20);
int message, set = 0, Select, client[30], max_client = 30, i, max_set = Socket;
fd_set readfds, fds;
struct timeval timeout;
for(i = 0; i < max_client; i++){
client[i] = 0;
}
//Clear & Add
FD_ZERO(&fds);
FD_SET(Socket, &fds);
bool stop = false;
while(!stop) {
readfds = fds;
Select = select(max_set +1, &readfds, NULL, NULL, NULL);
if (Select == -1) {
perror("Select");
break;
}
if(FD_ISSET(Socket, &readfds)) {
if(set < max_client) {
client[set] = acceptFile(Socket,(struct sockaddr *) &sender, senderLength);
FD_SET(client[set], &fds);
if(client[set] > max_set)
max_set = client[set];
set++;
}
}
for(i = 0; i < set; i++) {
if(FD_ISSET(client[i], &readfds)){
message = recv(client[i], buffer, 20, 0);
buffer[message] = '\0';
printf("%s\n", buffer);
}
}
}
close(Socket);
return 0;
}
The client part is okay but after connecting to the server and the sending the first message, the server is not able to receive the message.
I having a lot of trouble dealing with the error. So please rectify the error.
You should enable all warnings. Then you'd see the reason immediately: acceptFile does not return anything, therefore client[set] is set to garbage.
Related
I am pretty new to socket programming and the C language. I want to teleoperate a robot over the internet for that I have to send some values to a robot computer. Here is my code...
x = state.position_val[0];
y = state.position_val[1];
z = state.position_val[2];
Rx = state.gimbal_joints[0]*1000;
Ry= state.gimbal_joints[1]*1000;
Rz = state.gimbal_joints[2]*1000;
double arr[7] = { x, y, z, Rx, Ry, Rz, btonn };
SAFEARRAY* psa = SafeArrayCreateVector(VT_R8, 0, 7);
void* data;
SafeArrayAccessData(psa, &data);
CopyMemory(data, arr, sizeof(arr));
SafeArrayUnaccessData(psa);
return psa;
These are the code snippets under the while loop at each loop this code gets the state value of the robot and creates an array that is further used for teleoperation. I need to send this array over the internet to another computer.
Please help me how to do this?
I have tested this on Windows machine
Go to https://ngrok.com create an account
your robot should run ngrok client use following commands
ngrok authtoken xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ngrok tcp 80
Forwarding tcp://3.tcp.ngrok.io:15842 -> localhost:80
Here ngrok will assign a local PORT to 80 and random port to outside network ie Interner exposed port. You have to add 80 and that port to your firewall rules of robot network device).
Goto https://whatismyipaddress.com/hostname-ip here put 3.tcp.ngrok.io Look IP address box from ngrok console out. You will get your robot's global IP. that you can connect to your robot from anywhere in the world.
Following are the Client and Server examples that you can compile and run.
gcc .\Client.c -o Client
gcc .\Server.c -o Server
Client.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<unistd.h>
//Create a Socket for server communication
short SocketCreate(void)
{
short hSocket;
printf("Create the socket\n");
hSocket = socket(AF_INET, SOCK_STREAM, 0);
return hSocket;
}
//try to connect with server
int SocketConnect(int hSocket)
{
int iRetval=-1;
int ServerPort = 15842; // ngroks external tcp port
struct sockaddr_in remote= {0};
remote.sin_addr.s_addr = inet_addr("3.134.xxx.xxx"); //Robot IP
remote.sin_family = AF_INET;
remote.sin_port = htons(ServerPort);
iRetval = connect(hSocket,(struct sockaddr *)&remote,sizeof(struct sockaddr_in));
return iRetval;
}
// Send the data to the server and set the timeout of 20 seconds
int SocketSend(int hSocket,char* Rqst,short lenRqst)
{
int shortRetval = -1;
struct timeval tv;
tv.tv_sec = 20; /* 20 Secs Timeout */
tv.tv_usec = 0;
if(setsockopt(hSocket,SOL_SOCKET,SO_SNDTIMEO,(char *)&tv,sizeof(tv)) < 0)
{
printf("Time Out\n");
return -1;
}
shortRetval = send(hSocket, Rqst, lenRqst, 0);
return shortRetval;
}
//receive the data from the server
int SocketReceive(int hSocket,char* Rsp,short RvcSize)
{
int shortRetval = -1;
struct timeval tv;
tv.tv_sec = 20; /* 20 Secs Timeout */
tv.tv_usec = 0;
if(setsockopt(hSocket, SOL_SOCKET, SO_RCVTIMEO,(char *)&tv,sizeof(tv)) < 0)
{
printf("Time Out\n");
return -1;
}
shortRetval = recv(hSocket, Rsp, RvcSize, 0);
printf("Response %s\n",Rsp);
return shortRetval;
}
//main driver program
int main(int argc, char *argv[])
{
int hSocket, read_size;
struct sockaddr_in server;
char SendToServer[100] = {0};
char server_reply[200] = {0};
//Create socket
hSocket = SocketCreate();
if(hSocket == -1)
{
printf("Could not create socket\n");
return 1;
}
printf("Socket is created\n");
//Connect to remote server
if (SocketConnect(hSocket) < 0)
{
perror("connect failed.\n");
return 1;
}
printf("Sucessfully conected with server\n");
printf("Enter the Message: ");
gets(SendToServer);
//Send data to the server
SocketSend(hSocket, SendToServer, strlen(SendToServer));
//Received the data from the server
read_size = SocketReceive(hSocket, server_reply, 200);
printf("Server Response : %s\n\n",server_reply);
close(hSocket);
shutdown(hSocket,0);
shutdown(hSocket,1);
shutdown(hSocket,2);
return 0;
}
Server.c
#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<unistd.h>
short SocketCreate(void)
{
short hSocket;
printf("Create the socket\n");
hSocket = socket(AF_INET, SOCK_STREAM, 0);
return hSocket;
}
int BindCreatedSocket(int hSocket)
{
int iRetval=-1;
int ClientPort = 80; //Robot local port
struct sockaddr_in remote= {0};
/* Internet address family */
remote.sin_family = AF_INET;
/* Any incoming interface */
remote.sin_addr.s_addr = htonl(INADDR_ANY);
remote.sin_port = htons(ClientPort); /* Local port */
iRetval = bind(hSocket,(struct sockaddr *)&remote,sizeof(remote));
return iRetval;
}
int main(int argc, char *argv[])
{
int socket_desc, sock, clientLen, read_size;
struct sockaddr_in server, client;
char client_message[200]= {0};
char message[100] = {0};
const char *pMessage = "hello aticleworld.com";
//Create socket
socket_desc = SocketCreate();
if (socket_desc == -1)
{
printf("Could not create socket");
return 1;
}
printf("Socket created\n");
//Bind
if( BindCreatedSocket(socket_desc) < 0)
{
//print the error message
perror("bind failed.");
return 1;
}
printf("bind done\n");
//Listen
listen(socket_desc, 3);
//Accept and incoming connection
while(1)
{
printf("Waiting for incoming connections...\n");
clientLen = sizeof(struct sockaddr_in);
//accept connection from an incoming client
sock = accept(socket_desc,(struct sockaddr *)&client,(socklen_t*)&clientLen);
if (sock < 0)
{
perror("accept failed");
return 1;
}
printf("Connection accepted\n");
memset(client_message, '\0', sizeof client_message);
memset(message, '\0', sizeof message);
//Receive a reply from the client
if( recv(sock, client_message, 200, 0) < 0)
{
printf("recv failed");
break;
}
printf("Client reply : %s\n",client_message);
if(strcmp(pMessage,client_message)==0)
{
strcpy(message,"Hi there !");
}
else
{
strcpy(message,"Invalid Message !");
}
// Send some data
if( send(sock, message, strlen(message), 0) < 0)
{
printf("Send failed");
return 1;
}
close(sock);
sleep(1);
}
return 0;
}
You can now send receive data between robot and your computer
I would like to add the functionality of evaluating arithmetic expressions for my simple client server application but do not know how. A client should be asked to input an arithmetic expression and the server should return an evaluation of that expression. The expression should separated into operation(+,-,/,*) and two non negative integer arguments. Server: This must implement an “Arithmetic Service” consisting of a dispatcher and the four operations
add, subtract, multiply and divide which should have identical prototypes:
Status op( int , int , int *); // the last argument is for the result
CLIENT CODE
#include "connection.h"
int clientSocket, z;
SocketAddress serverAddr, clientAddr, rSA;
socklen_t addr_size;
char _message[SIZE], reply[SIZE];
void main(int argc, char **argv)
{
int aPort = IPPORT_RESERVED + getuid();
int rPort = IPPORT_RESERVED + getuid() + 1;
if (argc <= 1)
{
printf("\nUsage: client server_name ??\n example client 127.0.0.1\n");
printf("Use q to close the session.\n");
exit(BAD);
}
z = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
makeReceiverSA(&rSA, rPort);
clientSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (clientSocket < 0)
{
perror("Socket creation failed!");
exit(BAD);
}
else
{
makeLocalSA(&clientAddr);
}
bind(z, (struct sockaddr *)&rSA, sizeof(SocketAddress));
if (bind(clientSocket, (struct sockaddr *)&clientAddr, sizeof(SocketAddress)) != 0)
{
perror("Socket binding failed!");
close(clientSocket);
exit(BAD);
}
printSA(clientAddr);
makeDestSA(&serverAddr, argv[1], aPort);
makeReceiverSA(&rSA, rPort);
printSA(serverAddr);
while (strlen(_message) != 1 && _message[0] != 'q')
{
printf("\nEnter message to send: ");
fgets(_message, SIZE, stdin);
Message m, r;
memcpy(m.data, _message, strlen(_message));
m.length = strlen(_message);
r.length = SIZE;
if (DoOperation(&m, &r, clientSocket, serverAddr) == OK)
{
memcpy(r.data, reply, strlen(reply));
printf("\nResponse: %s\n", r.data);
}
}
}
Status DoOperation(Message *message, Message *reply, int s, SocketAddress serverSA)
{
Status ret;
if (message->length > SIZE)
{
printf("\nError: \n\tCode: %d\n\tMessage: BAD Message Length\n", WRONGLENGTH);
return WRONGLENGTH;
}
ret = UDPsend(s, message, serverSA);
if (ret == BAD)
return BAD;
ret = UDPreceive(z, reply, &rSA);
if (ret == BAD)
return BAD;
return OK;
}
Status UDPsend(int s, Message *m, SocketAddress dest)
{
ssize_t n;
n = sendto(s, m->data, m->length, 0, (struct sockaddr *)&dest, sizeof(SocketAddress));
if (n < 0)
{
printf("\nError: \n\tCode: %d\n\tMessage: Unrecoverable error\n", BAD);
return BAD;
}
if (n != m->length)
return OK;
}
Status UDPreceive(int s, Message *m, SocketAddress *origin)
{
ssize_t n;
socklen_t a = sizeof(SocketAddress);
n = recvfrom(s, reply, SIZE, 0, (struct sockaddr *)&origin, &a);
if (n < 0)
{
printf("\nError: \n\tCode: %d\n\tMessage: Unrecoverable error\n", BAD);
return BAD;
}
if (strlen(reply) > SIZE)
{
printf("\nError: \n\tCode: %d\n\tMessage: BAD Message Length\n", WRONGLENGTH);
return WRONGLENGTH;
}
return OK;
}
HEADER FILE
#include <stdio.h> /* standard C i/o facilities */
#include <unistd.h> /* Unix System Calls */
#include <sys/types.h> /* system data type definitions */
// #include <sys/wait.h> /* System Socket wait definitions */
#include <sys/socket.h> /* socket specific definitions */
#include <netinet/in.h> /* INET constants and stuff */
#include <arpa/inet.h> /* IP address conversion stuff */
#include <string.h>
#include <stdlib.h> /* needed for atoi() */
#include <netdb.h>
struct hostent *gethostbyname() ;
#ifndef SIZE
#define SIZE 1000
#endif
typedef enum {
OK, // operation successful
BAD, // unrecoverable error
WRONGLENGTH // BAD message length supplied
} Status;
typedef struct sockaddr_in SocketAddress;
typedef struct
{
unsigned int length;
unsigned char data[SIZE];
} Message;
extern void printSA(SocketAddress sa) ;
extern void makeDestSA(SocketAddress * sa, char *hostname, int port) ;
extern void makeLocalSA(SocketAddress *sa) ;
extern void receiver(int port) ;
extern void sender(char *message1, char *machine, int port);
extern Status DoOperation(Message *message, Message *reply, int s, SocketAddress serverSA);
extern Status GetRequest(Message *callMessage, int s, SocketAddress *clientSA);
extern Status SendReply(Message *replyMessage, int s, SocketAddress clientSA);
/*
* To return BAD if sendto/recvfrom return negatives
*/
extern Status UDPsend(int s, Message *m, SocketAddress dest);
extern Status UDPreceive(int s, Message *m, SocketAddress *origin);
/*print a socket address */
void printSA(SocketAddress sa)
{
printf("sa = %d, %s, %d\n",
sa.sin_family, inet_ntoa(sa.sin_addr), ntohs(sa.sin_port));
}
/* make a socket address for a destination whose machine and port
are given as arguments */
void makeDestSA(SocketAddress * sa, char *hostname, int port)
{
struct hostent *host;
sa->sin_family = AF_INET;
if((host = gethostbyname(hostname))== NULL) {
printf("Unknown host name\n");
exit(-1);
}
sa->sin_addr = *(struct in_addr *) (host->h_addr);
sa->sin_port = htons(port);
}
/* make a socket address using any of the addressses of this computer
for a local socket on any port */
void makeLocalSA(SocketAddress *sa)
{
sa->sin_family = AF_INET;
sa->sin_port = htons(0);
sa->sin_addr.s_addr = htonl(INADDR_ANY);
}
/* make a socket address using any of the addressses of this computer
for a local socket on given port */
void makeReceiverSA(SocketAddress *sa, int port)
{
sa->sin_family = AF_INET;
sa->sin_port = htons(port);
sa->sin_addr.s_addr = htonl(INADDR_ANY);
}
/*receive two messages via s new socket,
print out the messages received and close the socket
bind to any of the addresses of this computer
using port given as argument */
void receiver(int port)
{
char message1[SIZE], message2[SIZE];
SocketAddress mySocketAddress, aSocketAddress;
int s, n;
socklen_t aLength;
int i;
if((s = socket(AF_INET, SOCK_DGRAM, 0))<0) {
perror("socket failed");
return;
}
makeReceiverSA(&mySocketAddress, port);
if( bind(s, (struct sockaddr *)&mySocketAddress, sizeof(SocketAddress))!= 0){
perror("Bind failed\n");
close(s);
return;
}
printSA(mySocketAddress);
aLength = sizeof(aSocketAddress);
aSocketAddress.sin_family = AF_INET;
if((n = recvfrom(s, message1, SIZE, 0, (struct sockaddr *)&aSocketAddress, &aLength))<0)
perror("Receive 1") ;
else{
printSA(aSocketAddress);
for(i=0; i<n; i++) printf("M:%d", message1[i]);
printf(" Received Message:(%s)length = %d \n",
message1,n);
}
if((n = recvfrom(s, message2, SIZE, 0, (struct sockaddr *)&aSocketAddress, &aLength))<0)
perror("Receive 2");
else {
printf("Received Message:(%s)length = %d \n",
message2,n);
}
close(s);
}
/*do send after receive ready, open socket
bind socket to local internet port
use any of the local computer's addresses
send two messages with given lengths to machine and port
close socket
*/
void sender(char *message1,char *machine, int port)
{
int s, n;
char message[SIZE];
SocketAddress mySocketAddress, yourSocketAddress;
if(( s = socket(AF_INET, SOCK_DGRAM, 0))<0) {
perror("socket failed");
return;
}
/*
if((x = setsockopt(s, SOL_SOCKET, SO_BROADCAST, &arg, sizeof(arg))<0)
perror("setsockopt SO_BROADCAST---");
exit(-1);
*/
makeLocalSA(&mySocketAddress);
if( bind(s, (struct sockaddr *)&mySocketAddress, sizeof(SocketAddress))!= 0){
perror("Bind failed\n");
close (s);
return;
}
printSA(mySocketAddress);
makeDestSA(&yourSocketAddress,machine, port);
printSA(yourSocketAddress);
strcpy(message,message1);
if( (n = sendto(s, message, strlen(message), 0, (struct sockaddr *)&yourSocketAddress,
sizeof(SocketAddress))) < 0)
perror("Send failed\n");
if(n != strlen(message)) printf("sent %d\n",n);
close(s);
}
#include <sys/time.h>
/* use select to test whether there is any input on descriptor s*/
int anyThingThere(int s)
{
unsigned long read_mask;
struct timeval timeout;
int n;
timeout.tv_sec = 1; /*seconds wait*/
timeout.tv_usec = 0; /* micro seconds*/
read_mask = (1<<s);
if((n = select(32, (fd_set *)&read_mask, 0, 0, &timeout))<0)
perror("Select fail:\n");
// else printf("n = %d\n", n);
return n;
}
SERVER CODE
#include "connection.h"
int serverSocket;
SocketAddress serverAddr, clientAddr;
socklen_t addr_size, n;
int i;
char _message[SIZE];
int main(int argc, char **argv)
{
int aPort = IPPORT_RESERVED + getuid();
serverSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (serverSocket < 0)
{
perror("Socket creation failed!\n");
exit(BAD);
}
else
{
makeReceiverSA(&serverAddr, aPort);
}
if (bind(serverSocket, (struct sockaddr *)&serverAddr, sizeof(SocketAddress)) != 0)
{
perror("Socket binding failed!\n");
close(serverSocket);
exit(BAD);
}
printSA(serverAddr);
addr_size = sizeof(clientAddr);
makeDestSA(&clientAddr, "127.0.0.1", aPort+1);
// clientAddr.sin_family = AF_INET;
while (strlen(_message) != 1 && _message[0] != 'q')
{
Message m, r;
char* art = "Message received!";
memcpy(r.data, art, strlen(art));
r.length = strlen(art);
if (anyThingThere(serverSocket) > 0)
if (GetRequest(&m, serverSocket, &clientAddr) == OK)
{
memcpy(_message, m.data, m.length);
printf("\nReceived Message: %s\n", m.data);
Status ret = SendReply(&r, serverSocket, clientAddr);
}
}
}
Status SendReply(Message *replyMessage, int s, SocketAddress clientSA)
{
printSA(clientSA);
Status ret;
ret = UDPsend(s, replyMessage, clientSA);
return OK;
}
Status GetRequest(Message *callMessage, int s, SocketAddress *clientSA)
{
Status ret = UDPreceive(s, callMessage, clientSA);
if (ret == BAD)
return BAD;
if (strlen(_message) > SIZE)
{
printf("\nError: \n\tCode: %d\n\tMessage: BAD Message Length\n", WRONGLENGTH);
return WRONGLENGTH;
}
else
return OK;
}
Status UDPsend(int s, Message *m, SocketAddress dest)
{
ssize_t n;
n = sendto(s, m->data, m->length, 0, (struct sockaddr *)&dest, sizeof(SocketAddress));
if (n < 0)
{
perror("Send Error:");
printf("\nError: \n\tCode: %d\n\tMessage: Unrecoverable error\n", BAD);
return BAD;
}
if (n != m->length)
return OK;
}
Status UDPreceive(int s, Message *m, SocketAddress *origin)
{
ssize_t n;
socklen_t a = sizeof(SocketAddress);
n = recvfrom(s, _message, SIZE, 0, (struct sockaddr *)&origin, &a);
// printf("%ld\n", n);
// printf("%s\n", _message);
// memcpy(&m->data, _message, strlen(_message));
// printf("%s\n", m->data);
// m->length = strlen(_message);
if (n < 0)
{
printf("\nError: \n\tCode: %d\n\tMessage: Unrecoverable error\n", BAD);
return BAD;
}
if (strlen(_message) > SIZE)
{
printf("\nError: \n\tCode: %d\n\tMessage: BAD Message Length\n", WRONGLENGTH);
return WRONGLENGTH;
}
return OK;
}
I am new to socket programming. I wrote codes for UDP Client and Server which work fine on my computer. I want to run these programs on two different hosts, i.e. the Server on my computer and Client on my friend' computer. How do I do it without a router? Please mention if any specific changes are to be made in the code for the purpose.
Here's the code:
Receiver
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<string.h>
#include<unistd.h>
int main() {
int ret = socket(AF_INET, SOCK_DGRAM, 0);
if (ret == -1) {
printf("socket creation fails\n");
exit(0);
} else
printf("socket creation succeeds\n");
struct sockaddr_in sender;
int port;
printf("Enter port:");
scanf("%d", & port);
sender.sin_family = AF_INET;
sender.sin_port = htons(port);
sender.sin_addr.s_addr = INADDR_ANY;
int ret1;
ret1 = bind(ret, (struct sockaddr * ) & sender, sizeof(sender));
if (ret1 == -1) {
printf("socket binding fails\n");
exit(0);
}
printf("socket binding succeeds\n");
struct sockaddr_in receiver;
char str[15], str2[15];
int addrlen = sizeof(receiver);
while (1) {
int rec = recvfrom(ret, str, sizeof(str), 0, (struct sockaddr * ) & receiver, & addrlen);
printf("Received:");
str[rec] = '\0';
if (strcmp(str, "exit") == 0)
break;
if (rec == -1) {
printf("recvfrom fails\n");
exit(0);
}
printf("%s\n", str);
printf("Enter :");
scanf("%s", str2);
int recsend = sendto(ret, str2, strlen(str2), 0, (struct sockaddr * ) & receiver, sizeof(receiver));
if (recsend == -1) {
printf("sendto fails");
exit(0);
}
if (strcmp(str2, "exit") == 0)
break;
}
close(ret);
return 0;
}
Sender
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<string.h>
#include<unistd.h>
int main() {
int ret = socket(AF_INET, SOCK_DGRAM, 0);
if (ret == -1) {
printf("\nsocket creation fails");
exit(0);
} else
printf("\nsocket creation succeeds");
struct sockaddr_in receiver;
int port;
printf("\nEnter port:");
scanf("%d", & port);
receiver.sin_family = AF_INET;
receiver.sin_port = htons(port);
receiver.sin_addr.s_addr = INADDR_ANY;
char str[15], str2[15];
int addrlen1 = sizeof(receiver);
struct sockaddr_in sender;
int addrlen = sizeof(sender);
while (1) {
printf("Enter:");
scanf("%s", str);
int send = sendto(ret, str, strlen(str), 0, (struct sockaddr * ) & receiver, addrlen1);
if (send == -1) {
printf("sendto fails");
exit(0);
}
if (strcmp(str, "exit") == 0)
break;
int senrec = recvfrom(ret, str2, sizeof(str2), 0, (struct sockaddr * ) & sender, & addrlen);
printf("\n");
printf("Received:");
str2[senrec] = '\0';
if (strcmp(str2, "exit") == 0)
break;
if (senrec == -1) {
printf("recvfrom fails\n");
exit(0);
}
printf("%s\n", str2);
}
close(ret);
return 0;
}
Connect both to different networks and get your server's ip address.
Change your client's receiver ip and port to:
receiver.sin_addr.s_addr = inet_addr("8.8.8.8"); // Ip address of your server.
receiver.sin_port=htons(port); // Whatever port your server is listening to
I have read some example and manual about select and accept but I still can't figure out where I did wrong.
I tried to let server communicate with multiple clients. But when I execute server first, then execute client, server will immediately cause segmentation fault( when i == sockfd in server.c). And I tried to print some strings to check which statement cause wrong, it even no print anything after if (i == sockfd). So I really have no idea how to move on, are there any suggestion?
Server.c
char inputBuffer[140] = {};
char message[] = {"Hi,this is server.\n"};
int sockfd = 0,forClientSockfd = 0;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1)
{
printf("Fail to create a socket.");
}
//socket creation
struct sockaddr_in serverInfo,clientInfo;
socklen_t addrlen = sizeof(clientInfo);
serverInfo.sin_family = PF_INET;
serverInfo.sin_addr.s_addr = INADDR_ANY;
serverInfo.sin_port = htons(PORT);
bind(sockfd,(struct sockaddr *)&serverInfo,sizeof(serverInfo));
listen(sockfd,5);
fd_set active_fd_set, read_fd_set;
int i;
struct sockaddr_in clientname;
size_t size;
/* Initialize the set of active sockets. */
FD_ZERO (&active_fd_set);
FD_SET (sockfd, &active_fd_set);
int fd_max = sockfd;
while (1)
{
/* Block until input arrives on one or more active sockets. */
//FD_ZERO (&active_fd_set);
//FD_SET (sockfd, &active_fd_set);
read_fd_set = active_fd_set;
if (select (fd_max+1, &read_fd_set, NULL, NULL, NULL) < 0)
{
printf("select fail\n");
}
/* Service all the sockets with input pending. */
for (i = 0; i <= fd_max; ++i)
{
//printf("%d\n",i);
if (FD_ISSET (i, &read_fd_set))
{
//printf("inner :%d %d\n",i,sockfd);
if (i == sockfd)
{
/* Connection request on original socket. */
//printf("A");
int new;
size = sizeof (clientname);
new = accept (sockfd,(struct sockaddr *) &clientname,&size);
if (new < 0)
{
printf("accept fail\n");
}
else
{
printf (
"Server: connect from host %s, port %hd.\n",
inet_ntoa (clientname.sin_addr),
ntohs (clientname.sin_port));
FD_SET (new, &active_fd_set);
if(new > fd_max)
{
fd_max = new;
}
}
}
else
{
/* Data arriving on an already-connected socket. */
if (read_from_client (i) < 0)
{
close (i);
FD_CLR (i, &active_fd_set);
}
}
}
}
}
return 0;
}
int read_from_client (int filedes)
{
char buffer[140];
int nbytes;
nbytes = recv (filedes, buffer, sizeof(buffer),0);
if (nbytes < 0)
{
/* Read error. */
perror ("read");
exit (EXIT_FAILURE);
}
else if (nbytes == 0)
/* End-of-file. */
return -1;
else
{
/* Data read. */
printf ("Server: got message: `%s'\n", buffer);
return 0;
}
}
client.c
int sockfd = 0;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1)
{
printf("Fail to create a socket.");
}
//socket connnection
struct sockaddr_in info;
bzero(&info,sizeof(info));
info.sin_family = PF_INET;
//localhost test
info.sin_addr.s_addr = inet_addr(LOCALHOST);
info.sin_port = htons(PORT);
int err;
char *p;
//Send a message to server
err = connect(sockfd,(struct sockaddr *)&info,sizeof(info));
if(err==-1)
printf("Connection error");
while(1)
{
char message[140];
char receiveMessage[140] = {};
fgets(message,140,stdin);
//scanf("%*[^\n]",message);
//printf("%s",message);
/*if(p=strchr(message,'\n')){
*p = 0;
}else{
scanf("%*[^\n]");
scanf("%c");
}
fgets(message,140,stdin);*/
//scanf("%s",message);
send(sockfd,message,sizeof(message),0);
//printf("RCV");
//recv(sockfd,receiveMessage,sizeof(receiveMessage),0);
//printf("%s\n",receiveMessage);
}
thanks !!
Basically i'm trying to do a server-client program that communicates with sockets.
I find it strange that the server, once started it doesn't even print the first line. Why is this?
There must be something that's sliping from me and I really need to know what.
Server.c
int rvsock;
void stop(int sig){
close(rvsock);
}
void* worker(void* p){
struct mymsg m;
int err;
int sock = (int)p;
err = recv(sock,&m,sizeof(m),0);
if(err < 0){
printf("Failed to receive");
exit(1);
}
m.a = ntohl(m.a);
m.b = ntohl(m.b);
m.c = ntohl(m.c);
m.ip = ntohl(m.ip);
printf("Received numbers: %d %d %d from IP:%d", m.a,m.b,m.c,m.ip);
if(m.a < m.b && m.b <= m.c)
m.a = m.c;
else if(m.a < m.b && m.b >= m.c)
m.a = m.b;
else if(m.a > m.b && m.b <= m.c)
m.a = m.a;
m.a = htonl(m.a);
m.b = htonl(m.b);
m.c = htonl(m.c);
err = send(sock, &m,sizeof(m),0);
if(err < 0){
printf("Failed to send!");
close(sock);
return NULL;
}
close(sock);
return NULL;
}
int main(int argc, char** argv) {
printf("DAFUQ"); //It doesn't even print this. Why?
int port;
int sock;
int err;
unsigned int len;
struct sockaddr_in saddr;
struct sockaddr_in caddr;
pthread_t w[100];
int wn = 0;
int i;
sscanf(argv[1], "%d", &port);
signal(SIGINT, stop);
rvsock = socket(AF_INET, SOCK_STREAM, 0);
if(rvsock < 0) {
perror("Failed to create socket");
exit(1);
}
memset(&saddr, 0, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = INADDR_ANY;
saddr.sin_port = htons(port);
err = bind(rvsock, (struct sockaddr*)&saddr,
sizeof(struct sockaddr_in));
if(err < 0) {
perror("Failed to bind");
exit(1);
}
err = listen(rvsock, 5);
if(err < 0) {
perror("Failed to listen");
close(rvsock);
exit(1);
}
while(1) {
len = sizeof(struct sockaddr_in);
sock = accept(rvsock, (struct sockaddr*)&caddr, &len);
if(sock < 0) {
perror("Failed to accept");
break;
}
pthread_create(&w[wn], 0, worker, (int*)sock);
wn++;
}
for(i=0; i<wn; i++) {
pthread_join(w[i], 0);
}
return 0;
}
client.c
int main(int argc, char** argv){
int sock;
int err;
int port;
struct sockaddr_in saddr;
struct mymsg m;
sscanf(argv[1], "%d", &port);
sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock < 0){
printf("failed to create");
exit(1);
}
memset(&saddr, 0, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
saddr.sin_port = htons(port);
err = connect(sock, (struct sockaddr*)&saddr, sizeof(struct sockaddr_in));
if(err < 0){
perror("Failed to connect!");
exit(1);
}
printf("give a:");scanf("%d",&m.a);
printf("give b:");scanf("%d",&m.b);
printf("give c:");scanf("%d",&m.c);
m.a = htonl(m.a);
m.b = htonl(m.b);
m.c = htonl(m.c);
send(sock,&m,sizeof(m),0);
return 0;
}
message.h
struct mymsg{
int a;
int b;
int c;
int ip;
};
In your server you have this line. printf prints to the stdout FILE which is opened for you when you start your program.
printf("DAFUQ"); //It doesn't even print this. Why?
man stdout provides the following information about stdout:
The stream stdout is line-buffered
when it points to a terminal. Partial lines will not appear until
fflush(3) or exit(3) is called, or a newline is printed.
You don't print a newline, you don't flush stdout and your program doesn't exit, therefore none of the conditions required to print your output to the terminal are met.
Therefore in order to print the line you have 3 options:
1
printf("DAFUQ"); //It doesn't even print this. Why?
fflush(stdout);
2
printf("DAFUQ\n"); /*notice added '\n'*/
3
call exit() after you print ( not very helpful probably).