I've been trying to receive data on a server socket from a client with the following code,
server.c
int startServer(uint16_t myPort)
{
int listenFd = 0, connfd = 0;
struct sockaddr_in serv_addr;
listenFd = socket(AF_INET, SOCK_STREAM, 6);
if (listenFd == -1) {
perror("socket");
return EXIT_FAILURE;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(myPort);
if (-1 == bind(listenFd, (struct sockaddr*)&serv_addr, sizeof(serv_addr))) {
perror("bind");
return EXIT_FAILURE;
}
if (-1 == listen(listenFd, 10)) {
perror("listen");
return EXIT_FAILURE;
}
printf("Server listening on %d\n", myPort);
int n = 0, k;
char recvBuff[1024];
struct sockaddr_in conn_addr;
unsigned int len = sizeof(conn_addr);
while(1)
{
connfd = accept(listenFd, (struct sockaddr*)NULL, NULL);
n = recv(connfd, &recvBuff, 1023, 0);
printf("Recd: %d bytes\n",n);
for (k=0; k<16; ++k) { printf("%d: 0x%02X, ", k, recvBuff[k]); }
sleep(1);
}
}
and in client.c
int main(int argc, char *argv[])
{
int sockfd = 0, n = 0;
struct sockaddr_in serv_addr;
if(argc != 2)
{
printf("\n Usage: %s <ip of server> \n",argv[0]);
return 1;
}
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Error : Could not create socket \n");
return 1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(5000);
if(inet_pton(AF_INET, argv[1], &serv_addr.sin_addr)<=0)
{
printf("\n inet_pton error occured\n");
return 1;
}
if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\n Error : Connect Failed \n");
return 1;
}
uint32_t dataVal = 0xa0b0c0d0;
int res = write(sockfd, (void*)&dataVal, sizeof(dataVal));
printf("%d bytes sent\n", res);
close(sockfd);
return 0;
}
However with this I see the server saying it received the bytes but the line after that printing the bytes (in a for loop) doesn't ever seem to be executed. Does anyone know what I am doing wrong here?
Add printf("\n"); after the for loop, or "\n" to the printf inside the for loop.
printf writes to stdout, which is buffered. This means that output will not display until the buffer is filled, flushed, or a newline is sent. As such, it is easiest to ensure output by sending a newline.
Related
This question already has answers here:
Two-way communication in socket programming using C
(5 answers)
Closed 5 years ago.
I am fairly new to sockets and understand the point of a server client relationship. I was just wondering if there is some sort of way for the client to return a response to the server in c.
Im thinking, should I use the same socket connection, or create another file descriptor within my client to send it to my server. Also is there a better way to implement this?
The main goal is to have bidirectional communication.
I have provided my example code below:
Server:
void connection(char* sentMessage){
int listenfd = 0, connfd = 0;
struct sockaddr_in serv_addr;
char sendBuff[1025];
time_t ticks;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_addr, '0', sizeof(serv_addr));
memset(sendBuff, '0', sizeof(sendBuff));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(5000);
bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
listen(listenfd, 10);
while(1)
{
connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
ticks = time(NULL);
snprintf(sendBuff, sizeof(sendBuff), "%.90s\r\n", sentMessage);
write(connfd, sendBuff, strlen(sendBuff));
printf("Snoopy Detected: %s", sendBuff);
close(connfd);
sleep(1);
}
}
int main(int argc, char *argv[])
{
//construct a string to pass to the client
char* protocol = "eax:valuevlaue, ebx:asdjasdjasd, ecx:sadafw, edx:asdfsasd";
connection(protocol);
}
Client:
int main(int argc, char *argv[])
{
int sockfd = 0, n = 0;
char recvBuff[1024];
struct sockaddr_in serv_addr;
if(argc != 2)
{
printf("\n Usage: %s <ip of server> \n",argv[0]);
return 1;
}
memset(recvBuff, '0',sizeof(recvBuff));
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Error : Could not create socket \n");
return 1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(5000);
if(inet_pton(AF_INET, argv[1], &serv_addr.sin_addr)<=0)
{
printf("\n inet_pton error occured\n");
return 1;
}
if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\n Error : Connect Failed \n");
return 1;
}
while ( (n = read(sockfd, recvBuff, sizeof(recvBuff)-1)) > 0)
{
recvBuff[n] = 0;
printf("Input: %s\n", recvBuff);
//parse it into eax, and such
char input[4][40];
char *ch;
int i = 0;
ch = strtok(recvBuff, ",");
while (ch != NULL) {
strcpy(input[i], ch);
ch = strtok(NULL, " ,");
i++;
}
//
// After this, do what you'd like with the input from donor
// And return the result back to the server
//
int j;
for(j = 0; j < 4 ; j++){
printf("%s\n", input[j]);
}
}
if(n < 0)
{
printf("\n Read error \n");
}
return 0;
}
Oh, I did it!
So apparently, sockets are inherently bidirectional, so all I had to do is write() back to the sockfd and read it from the server side!
I am trying to connect to my local UNIX server i made from another remote device. the Server is up and listening to the port i specified. i also added a new firewall rule to open that port but still my client cannot connect. it shows ERROR CONNECTION REFUSED
here is my server code
int main() {
int fd, i,svclient,rval,msg;
int clients[10], num_clients;
fd_set read_set,write_set;
char buf[100];
struct sockaddr_in addr;
if ( (fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket error");
exit(-1);
}
bzero((char *) &addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(4001);
//strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path)-1);
//strcpy(addr.sun_path, NAME);
if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
perror("bind error");
exit(-1);
}
printf("Bind complet...\n");
if (listen(fd, 20) == -1) {
perror("listen error");
exit(-1);
}
num_clients = 0;
int size = sizeof(fd);
while (1) {
int clientfd;
struct sockaddr_in client_addr;
int addrlen=sizeof(client_addr);
FD_ZERO(&read_set);
FD_SET(fd, &read_set);
for (i = 0; i < num_clients; i++) { //at first this part will not excute
FD_SET(clients[i], &read_set);
}
select(fd + num_clients + 1, &read_set, NULL, NULL, NULL);
if (FD_ISSET(fd, &read_set)) {
if ( (clients[num_clients++] = accept(fd,(struct sockaddr*)&client_addr,&addrlen)) == -1) {
perror("accept error");
continue;
}
/*printf("incoming message..................... !\n \n");*/
printf("%s:%d connected\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
}
for (i = 0; i < num_clients; i++) {
if (FD_ISSET(clients[i], &read_set)) {
msg = read(clients[i], buf, sizeof(buf));
if(msg > 0){
buf[msg] = 0;
int savedclnt = clients[i];
printf("%s \n \n", buf);
/*for(int p=0;p<num_clients;p++)
{
if( clients[p]!= savedclnt){
write(clients[p],buf,msg);
}
}*/
}
}
}
}
}
and my client
int main( )
{
struct uci_context *uci;
uci = uci_init();
int sockfd;
int ret;
struct sockaddr_in dest;
struct addrinfo hint, *res = NULL;
struct hostent *host;
char *hostip;
char *string;
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
{
puts("Unble to create socket");
exit(1);
}
hostip = ucix_get_option(uci, "pack_mon", "pack_monitoring", "address");
string = ucix_get_option(uci, "pack_mon", "pack_monitoring", "port");
bzero(&dest, sizeof(dest));
dest.sin_family = AF_INET;
dest.sin_port = htons(atoi(string));
memset(&hint, '\0', sizeof hint);
hint.ai_family = PF_UNSPEC;
hint.ai_flags = AI_NUMERICHOST;
printf(" %s- %s\n", hostip, string );
if(isdigit(hostip[0])){
ret = getaddrinfo(hostip, NULL, &hint, &res);// this is more efficient than inet_addr
if (ret) {
exit(1);
}
}else if( (host = gethostbyname(hostip)) != 0){
memcpy((char*)&dest.sin_addr , (char*)host->h_addr , (sizeof dest.sin_addr)+1);
}else{
exit(1);
printf("cannot resolve ip address");
}
if ( connect(sockfd, (struct sockaddr *)&dest, sizeof(dest)) < 0 )
{
perror("ERROR Connecting" );
exit(1);
}else{
printf("Port number %s is open.....\n",string);
}
char *message;
message = "help";
write(sockfd,message,strlen(message));
close(sockfd);
freeaddrinfo(res);
return 0;
}
FIREWALL RULE
sudo iptables -I INPUT -p tcp --dport 4001 -j ACCEPT
Error is :
192.168.10.155- 4001
ERROR Connecting: Connection refused
and this logs are coming from this codes :
printf(" %s- %s\n", hostip, string );
perror("ERROR Connecting");
exit(1);
Your client has no code to specify the IP address it wants to connect to. All the code that could do that has been commented out.
Update: Now your bug is here:
strncpy((char*)&dest.sin_addr , (char*)host->h_addr , sizeof dest.sin_addr);
The strncpy function is only suitable for C-style strings. You need to use memcpy or something similar. This will only copy part of the IP address if any octet other than its last one (in network byte order) is zero.
Update: Now your bug is here:
printf("%d\n", connect(sockfd, (struct sockaddr *)&dest, sizeof(dest)) < 0);
perror("hmmmm" );
exit(1);
This calls connect, then calls printf and then calls perror. The problem is, the call to printf can modify errno even if it succeeds. Thus your call to perror can print a totally irrelevant error message.
Iv'e tried to run server client between 2 computers in my local network in my house.
I failed with error 10049 in the client side. I thought it was something with firewall so I've tried to run it my computer(with threads), but still the same issue.
I'm failing at function "connect" with my output:
"error - connect failed. sockfd is 188, errno is 34, WSA is 10049"
here's my code.
app.c:
#include "client.h"
#include "server.h"
int main()
{
DWORD dwThreadID1, dwThreadID2;
CreateThread(
NULL, // default security attributes
0, // default stack size
(LPTHREAD_START_ROUTINE) apserver,
NULL, // no thread function arguments
0, // default creation flags
&dwThreadID1); // receive thread identifier
CreateThread(
NULL, // default security attributes
0, // default stack size
(LPTHREAD_START_ROUTINE) apClient,
NULL, // no thread function arguments
0, // default creation flags
&dwThreadID2); // receive thread identifier
while(1)
{}
return 0;
}
server.c:
#include "server.h"
int socketBind(int sockfd, int port){
struct sockaddr_in serv_addr;
ZeroMemory((char*) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(port);
if ( bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0 ){
// we can check errno for exact ERROR
printf("bind failed with errno %d\n",errno);fflush(NULL);
return ERROR;
}
if ( listen(sockfd, 100) == -1 ){
return ERROR;
}
return 1;
}
DWORD WINAPI apserver(LPVOID lpParam)
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) == SOCKET_ERROR) {
printf ("Error initialising WSA.\n");
return -1;
}
int sockfd; // server's listening socket's descriptor id
int port = 4997;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
while ( sockfd < 0 ){ // ERROR
printf("Listener socket creation failed with:%d, errno is %d\n",sockfd,errno);fflush(NULL);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
}
if ( socketBind(sockfd, port) == ERROR ){
printf("Socket bind failed with errno=%d\n",errno);fflush(NULL);
close(sockfd);
return ERROR;
}
printf("Starting to listen to other USERS!\n");fflush(NULL);
struct sockaddr_in cli_addr;
int clilen = sizeof(cli_addr); // length of address
// accept() returns the socket that will be used for Control Connection with the accepted client
printf("*************Waiting for other USERS************\n");fflush(NULL);
int newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
int readLength;
char command[(128+1)];
while(1)
{
ZeroMemory(command, sizeof(command));
readLength = read(newsockfd, command, 128+1);
if(readLength == 0)
{
continue;
}
if(readLength > 0)
{
printf(" here should be API's func to command %s", command);fflush(NULL);
}
else
{
close(sockfd);
close(newsockfd);
WSACleanup();
printf("Read failed with errno:%d\n",errno);fflush(NULL);
return ERROR;
}
}
close(sockfd);
close(newsockfd);
WSACleanup();
return 1;
}
client.c:
#include "client.h"
int verifyWrite(int sockfd, char* command){
int size = strlen(command);
int i=0, x=0;
for(i=0;i<size;){
x = write(sockfd, command, size);
if(x < 0){
return ERROR;
}
if(x >= 0) {
i += x;
}
}
return 0;
}
int sendToAll(char* message, int sockfd)
{
if ( verifyWrite(sockfd, message) < 0 )
{
printf("error while sending message\n");fflush(NULL);
}
return 0;
}
DWORD WINAPI apClient(LPVOID lpParam)
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) == SOCKET_ERROR) {
printf ("Error initialising WSA.\n");
return -1;
}
int port,sockfd;
struct sockaddr_in serv_addr;
sockfd = socket(AF_INET, SOCK_STREAM, 0); //creating control connection
while(sockfd < 0){
printf("error - sockfd = %d\n",sockfd);fflush(NULL);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
}
port = 4997;
serv_addr.sin_addr.s_addr = inet_addr("192.168.x.x");
ZeroMemory((char*)&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(port);
while(connect(sockfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr)) < 0){
printf("error - connect failed. sockfd is %d, errno is %d, WSA is %d\n",sockfd,errno,WSAGetLastError());fflush(NULL);
}
printf("\n opened connection to %s\n", "192.168.x.x");fflush(NULL);
int i = 0;
while(i< 6)
{
sendToAll("just a message", sockfd);
i++;
}
WSACleanup();
return 0;
}
Windows socket error 10049 is WSAEADDRNOTAVAIL, and if you read about it you will see that
connect, ... when the remote address or port is not valid for a remote computer (for example, address or port 0).
The reason is very simple:
serv_addr.sin_addr.s_addr = inet_addr("192.168.x.x");
ZeroMemory((char*)&serv_addr, sizeof(serv_addr));
You clear the structure after you set the address you want to connect to.
I have a multi-client chat server and for some reason only the first client is being added. I used a tutorial to help get me started. I have included my code below. When I try and add another client it doesnt appear to be added. If I add one client I get a response from the server like I want but only the first message I enter then after that it stops sending correctly.
Server Code:
int main(void)
{
struct sockaddr_in my_addr, cli_addr[10],cli_temp;
int sockfd;
socklen_t slen[10],slen_temp;
slen_temp = sizeof(cli_temp);
char buf[BUFLEN];
int clients = 0;
int client_port[10];
if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
{
printf("test\n");
err("socket");
}else{
printf("Server : Socket() successful\n");
}
bzero(&my_addr, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(PORT);
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(sockfd, (struct sockaddr* ) &my_addr, sizeof(my_addr))==-1)
{
err("bind");
}else{
printf("Server : bind() successful\n");
}
int num_clients = 0;
while(1)
{
//receive
printf("Receiving...\n");
if (recvfrom(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&cli_temp, &slen_temp)==-1)
err("recvfrom()");
if (clients <= 10) {
cli_addr[clients] = cli_temp;
client_port[clients] = ntohs(cli_addr[clients].sin_port);
clients++;
printf("Client added\n");
//printf("%d",clients);
int i;
for(i=0;sizeof(clients);i++) {
sendto(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&cli_addr[i], sizeof(cli_addr[i]));
}
}
}
close(sockfd);
return 0;
}
I have included the client code as well in case it helps.
void err(char *s)
{
perror(s);
exit(1);
}
sig_atomic_t child_exit_status;
void clean_up_child_process (int signal_number)
{
/* Clean up the child process. */
int status;
wait (&status);
/* Store its exit status in a global variable. */
child_exit_status = status;
}
int main(int argc, char** argv)
{
struct sockaddr_in serv_addr;
int sockfd, slen=sizeof(serv_addr);
char buf[BUFLEN];
struct sigaction sigchld_action;
memset (&sigchld_action, 0, sizeof (sigchld_action));
sigchld_action.sa_handler = &clean_up_child_process;
sigaction (SIGCHLD, &sigchld_action, NULL);
int pid,ppid;
if(argc != 2)
{
printf("Usage : %s <Server-IP>\n",argv[0]);
exit(0);
}
if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
err("socket");
bzero(&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
if (inet_aton(argv[1], &serv_addr.sin_addr)==0)
{
fprintf(stderr, "inet_aton() failed\n");
exit(1);
}
pid = fork();
if (pid<0) {
err("Fork Error");
}else if (pid==0) {
//child process will receive from server
while (1) {
bzero(buf,BUFLEN);
//printf("Attempting to READ to socket %d: ",sockfd);
fflush(stdout);
//recvfrom here
if (recvfrom(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&serv_addr, &slen)==-1)
err("recvfrom()");
printf("The message from the server is: %s \n",buf);
if (strcmp(buf,"bye\n") == 0) {
ppid = getppid();
kill(ppid, SIGUSR2);
break;
}
}
}else {
//parent will send to server
while(1){
printf("Please enter the message to send: ");
bzero(buf,BUFLEN);
fgets(buf,BUFLEN,stdin);
printf("Attempting to write to socket %d: ",sockfd);
fflush(stdout);
//send to here
if (sendto(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&serv_addr, slen)==-1)
{
err("sendto()");
}
}
}
close(sockfd);
return 0;
}
Several problems jump out at me. First, every time you receive a message it will consider that to be a new client. Instead of just incrementing the clients variable for a message, you'll need to scan through the array to see if the source address is already present. Second, sizeof(clients) will return a static value (probably 4) depending on how many bytes an int occupies on your machine. That loop should be for( int i = 0; i < clients; i++ ).
You also have a variable named num_clients which is not used. Is that supposed to be there for something and maybe is causing some confusion?
Finally, instead of using the magic value 10 all over the place, use #define MAX_CONNECTIONS 10 and then replace all those numbers with MAX_CONNECTIONS. It's a lot easier to read and change later.
I'm sending a message (a greeting) from a server to a client. The server sends the data but the client is not receiving it and then the server jumps to a read because client have to reply with an input of the user. Can you tell me why I never receive the greeting message?
Server:
int
main(int argc, char **argv)
{
int listenfd, connfd;
socklen_t len;
struct sockaddr_in servaddr, cliaddr;
char buff[MAXLINE];
time_t ticks;
char message[50];
char temp_scale[2];
char recvdata[MAXLINE + 1];
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);/*----------------------------------------------------*/
servaddr.sin_port = htons(5678);
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
printf("Listening on port 5678...Press Ctrl+C to end server\n");
printf("Waiting for incoming connections...\n");
for ( ; ; )
{
len = sizeof(cliaddr);
connfd = Accept(listenfd, (SA *) &cliaddr, &len);
/*Client connects to server*/
printf("Connection from %s, port %d\n",
Inet_ntop(AF_INET, &cliaddr.sin_addr, buff, sizeof(buff)),
ntohs(cliaddr.sin_port));
snprintf(message, sizeof(message), "%s\r\n", "Welcome!");
Writen(connfd, message, strlen(message));
while ( (n = read(connfd, recvdata, MAXLINE)) > 0)
{
recvdata[n] = 0; /* null terminate*/
if (fputs(recvdata, stdout) == EOF)
err_sys("fputs error");
}
if (n < 0)
err_sys("read error");
Close(connfd);
}
}
Client:
int
main(int argc, char **argv)
{
int sockfd, n;
socklen_t len;
char recvline[MAXLINE + 1];
struct sockaddr_in servaddr, cliaddr;
char scale[2];
/*if (argc != 2)
err_quit("usage: a.out <IPaddress>");*/
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
err_sys("socket error");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(atoi(argv[2])); /*port passed through command line*/
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) /*The client translates the server address, passed on the command line*/
err_quit("inet_pton error for %s", argv[1]);
printf("Connect...\n");
if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
err_sys("connect error");
len = sizeof(cliaddr);
Getsockname(sockfd, (SA *) &cliaddr, &len);
printf("Local Address is: %s\n",
Sock_ntop((SA *) &cliaddr, sizeof(cliaddr)));
while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {
recvline[n] = 0; /* null terminate */
if (fputs(recvline, stdout) == EOF)
err_sys("fputs error");
}
if (n < 0)
err_sys("read error");
printf("Enter the thermal Unit ('C' Celsius, 'F' Farehnheit: ");
send_data(sockfd);
exit(0);
}
Thanks!