Sorry for a very generic sounding question.
let's say
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define SERVER_ADDRESS "123.456.789.012"
#define CLIENT_ADDRESS "123.456.789.013"
#define SERVER_TCP_PORT "1234"
#define CLIENT_TCP_PORT "1235"
int main()
{
printf("o halo thar");
int sockfd, new_sockfd, msg_len;
void * got_msg = "got ur msg!";
void * message;
struct sockaddr_in server_address, client_address;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
exit(1);
printf("socket is opened");
bzero((char * ) &server_address, sizeof(server_address));
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = htonl(SERVER_ADDRESS);
server_address.sin_port = htons(SERVER_TCP_PORT);
if (bind(sockfd, (struct sockaddr *) &server_address, sizeof(server_address)) < 0)
exit(1);
printf("socket is bound");
listen(sockfd,11);
printf("listening");
if (accept(sockfd, (struct sockaddr *) &client_address, sizeof(client_address)) < 0) // THE BAD LINE
exit(1);
printf("accepted");
int i;
for( i = 0; i < 11; i++)
{
msg_len = recv(sockfd, (void *) message, 10000, 0);
if (msg_len < 1)
exit(1);
printf("receiving msg");
if (send(sockfd, (void *) got_msg, 10000, 0) < 0);
exit(1);
printf("sending msg");
}
close(sockfd);
}
it should print abc if everything runs correctly. of course, my code doesn't. but i have localized the problem to this certain line of code which i'm calling somecode(). when i comment out somecode(), the program prints out ab (not c). however when not commented out, it prints nothing. so what kind of problem am i running into that affects previous statements? sorry for the vagueness. i'm just wondering how seeing somecode() is compiled fine, but when running, it influences executions of code that should be done before it reaches somecode()? Thanks guys.
EDIT:somecode() being
if (accept(sockfd, (struct sockaddr *) &client_address, sizeof(client_address)) < 0)
exit(1);
EDIT2:
sorry for being too vague. i even forgot to describe what happens to the program. it doesn't print anything out and i have to ctrl+c in order to get out of it.
Without seeing more code, anything that causes the program to exit unexpectedly (rather, be killed by the operating system) such as a segmentation fault or entering some form of code structure that does not allow it to return to your flow of execution, necessitating a kill via ctrl+c. Otherwise, the program should carry on without any issue.
What happens if you fflush(STDOUT) after each call to printf? Maybe your program is dying before printing all buffered output.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I'm really confused. I have a C server and it was working great, but then I added some code, and I thought it was working fine until my c program randomly started changing the value of an int to a negative value.
Basically I'm having my server output the total bytes sent and midway through the transmission, always around 2100000000 bytes, the total bytes becomes negative. Here's an example of my output file. The value can't just become negative if you look at my code. So I suspect it's something weirder.
"345000","1470253912","59203","5592","2069901108"
"348000","1470253912","475539","4194","2092449162"
"351000","1470253912","830291","2796","2112043464"
"354000","1470253913","243217","1398","2133985176"
"357000","1470253913","708686","13980","-2135434834"
"360000","1470253914","173646","9786","-2109094024"
"363000","1470253914","514938","6990","-2089413400"
Anyways the thing I added, I commented it out, and I still came across the same error. Just for reference it's commented out in my code under tags "NEW STUFF ADDED". (I added it because of this post: Terminating C program on command line, but make sure writer is finished writing
)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include <sys/time.h>
int PORT_NUM = 0;
int RecordRate = 3000;
FILE *fp;
typedef struct timeval timeval;
timeval time_;
void error(const char *msg)
{
perror(msg);
exit(1);
}
//NEW STUFF ADDED
//void sig_handler(int signo)
//{
// if (signo == SIGINT) {
// printf("received SIGINT\n");
// exit(0);
// fflush(fp);
// }
//}
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno;
socklen_t clilen;
char buffer[1000000];
struct sockaddr_in serv_addr, cli_addr;
int n;
PORT_NUM = atoi(argv[1]);
fp = fopen(argv[2],"w");
// NEW STUFF ADDED
// if (signal(SIGINT, sig_handler) == SIG_ERR)
// printf("\ncan't catch SIGINT\n");
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
//portno = atoi(argv[1]);
portno = PORT_NUM;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0)
error("ERROR on binding");
listen(sockfd,10);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr,
&clilen);
if (newsockfd < 0)
error("ERROR on accept");
int counter = 0;
int total_bytes_sent = 0;
while(1){
bzero(buffer,1000000);
n = read(newsockfd,buffer,999999);
if (n < 0) {
error("ERROR reading from socket");
}
else if (n != 0) {
total_bytes_sent += n;
gettimeofday(&time_, NULL);
if(counter%RecordRate==0){
printf("counter %d \n", counter);
printf("Bytes Sent %d \n", total_bytes_sent);
fprintf(fp,"\"%d\",\"%ld\",\"%d\",\"%d\",\"%d\"\n", counter, time_.tv_sec, time_.tv_usec, n,total_bytes_sent);
}
counter++;
}
}
fclose(fp);
close(newsockfd);
close(sockfd);
return 0;
}
I swear I'm not trolling. I feared it was what I added that did this, but once I commented it out I got the same error. The thing is the error only became present after I added the code. So causation, correlation, no link?
How can this happen? And why always around 2100000000 bytes.
It's not the end of the world. I mean I can just hardcode something that makes sure the value is always, positive but I'm curious as to how this happens. Thanks.
Simply because ordinary signed int variables overflow at 231-1 (2147483647) and become negative.
Since this order of magnitude is not enough to keep track of the values you need, you should be using a 64bit variable to that - declare your variable as long long - and take proper care of this change in the places you are outputting this value to a text stream, and you should be good.
First off, this is homework, so please no outright answers. I am writing a back and forth chat program in C. I'm extremely new to C (just started learning for this class). Currently I have three files:
server.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include "chat.h"
#define SERVER_PORT 1725
#define MAX_PENDING 5
#define MAX_LINE 256
int main()
{
struct sockaddr_in sin;
char buf[MAX_LINE];
int len;
int s, new_s;
struct chat_packet packet;
/* build address data structure */
bzero((char *)&sin, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(SERVER_PORT);
/* setup passive open */
if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0)
{
perror("simplex-talk: socket");
exit(1);
}
if ((bind(s, (struct sockaddr *)&sin, sizeof(sin))) < 0)
{
perror("simplex-talk: bind");
exit(1);
}
listen(s, MAX_PENDING);
/* wait for connection, then receive and print text */
while(1)
{
if ((new_s = accept(s, (struct sockaddr *)&sin, &len)) < 0)
{
perror("simplex-talk: accept");
exit(1);
}
/* Stay in the following loop until CTRL+C */
while (len = recv(new_s, &packet, sizeof(packet), 0))
{
fputs(packet.sender_name, stdout);
fputs(": ", stdout);
fputs(packet.data, stdout);
fputs("\nYou: ", stdout);
while (fgets(buf, sizeof(buf), stdin))
{
if(strlen(buf) > 144)
{
printf("Your message is too long. Please enter a new message.\n");
continue;
}
else
{
buf[MAX_LINE-1] = '\0';
strncpy(packet.data,buf,144);
char sender[8] = "Mason"; /*should be argv[index of name]*/
strncpy(packet.sender_name, sender, 8);
send(new_s, &packet, sizeof(packet),0);
}
}
}
close(new_s);
}
}
client.c
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include "chat.h"
#define SERVER_PORT 1725
#define MAX_LINE 256
int main(int argc, char * argv[])
{
FILE *fp;
struct hostent *hp;
struct sockaddr_in sin;
char *host;
char buf[MAX_LINE];
int s;
int len;
struct chat_packet packet;
if (argc==2)
{
host = argv[1];
}
else
{
fprintf(stderr, "usage: simplex-talk host\n");
exit(1);
}
/* translate host name into peer's IP address */
hp = gethostbyname(host);
if (!hp) {
fprintf(stderr, "simplex-talk: unknown host: %s\n", host);
exit(1);
}
/* build address data structure */
bzero((char *)&sin, sizeof(sin));
sin.sin_family = AF_INET;
bcopy(hp->h_addr, (char *)&sin.sin_addr, hp->h_length);
sin.sin_port = htons(SERVER_PORT);
/* active open */
if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0)
{
perror("simplex-talk: socket");
exit(1);
}
if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
{
perror("simplex-talk: connect");
close(s);
exit(1);
}
/* main loop: get and send lines of text */
while (fgets(buf, sizeof(buf), stdin))
{
if(strlen(buf) > 144)
{
printf("Your message is too long. Please enter a new message.\n");
continue; /*This allows the user to re-enter a message post-error*/
}
else
{
buf[MAX_LINE-1] = '\0';
strncpy(packet.data, buf, 144);
char sender[8] = "Abby"; /*should be argv[index of name]*/
strncpy(packet.sender_name, sender, 8);
send(s, &packet, sizeof(packet), 0);
recv(s, &packet, sizeof(packet),0);
fputs(packet.sender_name, stdout);
fputs(": ", stdout);
fputs(packet.data, stdout);
fputs("\nYou: ", stdout);
}
}
}
chat.h
#include <stdint.h> /* Needed for unsigned types */
#define MAX_DATA_LEN 144 /* So we are on 16-bit boundary */
#define USER_NAME_LEN 8
/* You must send this packet across the socket. Notice there are
* no pointers inside this packet. Why?*/
struct chat_packet {
u_short version; /* 16 bits -- Set to version 2 in code */
char sender_name[8]; /* 64 bits */
char data[MAX_DATA_LEN]; /* Message goes in here */
};
Everything except what is in the client and server while loops were given to me by my instructor. The base part of the assignment is getting back-and-forth chat functionality. I'm running everything in PuTTY using the command line. I duplicate the session and run client in one and server in the other. To run:
./client serverName
./server
I am able to go back and forth one time, and then nothing else sends or receives. I am still able to type, but the two sessions cannot see each other's messages past the first back and forth. I am not sure where my code is wrong. Any advice would be appreciated, as I'm very new to the language. Thanks in advance!
Okay, here's my hint: Think about what happens when you recv() zero characters. Also, check what happens when the server calls accept() vs. when the client calls connect().
You might also want to check the return values of your recv() calls more judiciously. (and send(), for that matter; if a call can fail, check its return value!) Here's a hint from the man recv page:
RETURN VALUES
These calls return the number of bytes received, or -1 if an error occurred.
Also, if you aren't familiar with a debugger (such as gdb), I would recommend learning it. In a pinch, you might consider adding printf() statements to your code, to figure out what is happening.
Also, think about where your "blocking calls" are. If you're not familiar with what it means to be a "blocking call", we call it "blocking" when you call a function, and that function doesn't return ("blocks") until some specified thing happens. For example, your accept() will block until a connection is accepted. Your fgets() will block until a line of text is received. send() would block if you've already sent too much data, and the buffer is full. recv() would block until you've received the specified number of bytes. recv() also has a behavior you might not expect, that you may need to account for:
If no messages are available at the socket, the receive call waits for a
message to arrive, unless the socket is nonblocking (see fcntl(2)) in
which case the value -1 is returned and the external variable errno set
to EAGAIN. The receive calls normally return any data available, up to
the requested amount, rather than waiting for receipt of the full amount
requested; this behavior is affected by the socket-level options
SO_RCVLOWAT and SO_RCVTIMEO described in getsockopt(2).
In your case, your packets might be small enough that you won't run into cases where you have to reassemble them yourself. But it couldn't hurt to check.
I think that gives you some avenues to explore...
I'm working on a university project, in which I have to connect a raspberry pi to an Android smartphone to control 2 motors.
We are new to socket programming, so we started out with an example we found on wikibooks and tried to modify in to our needs. We're now facing the problem, that the connection between server and client is very arbitrary and unstable, sometimes connecting, and after a brief disconnect doesnt connect again. The weird thing (for me) is, that after we edit the code above the part responsible for connection:
/* bind serv information to mysocket */
bind(mysocket, (struct sockaddr *)&serv, sizeof(struct sockaddr));
/* start listening, allowing a queue of up to 2 pending connection */
listen(mysocket, 2);
consocket = accept(mysocket, (struct sockaddr *)&dest, &socksize);
like inserting in a printf, the next time we launch the programm, everthing does work, sometimes two or three times, and then it just stops connecting.
I've searched all over google and so for a similar problem, but I haven't found an equivalent, so I turn to you directly now.
This is code for our server running on the raspberry pi, which also serves as a network hotspot:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <bcm2835.h>
#define PORTNUM 5298
#define MAXRCVLEN 1000
#define PIN9 RPI_GPIO_P1_21
#define PIN10 RPI_GPIO_P1_19
#define PIN11 RPI_GPIO_P1_23
#define PIN22 RPI_GPIO_P1_15
int setpins();
int forward();
int backward();
int main(int argc, char *argv[])
{
char msg[] = "Connected!\n";
char testchar[] = "stillthere?";
char quitstring[] = "quit";
char *recbuf;
int qflag = 0;
int lflag = 0;
int mysocket, consocket, len; /* socket used to listen for incoming connections */
struct sockaddr_in dest; /* socket info about the machine connecting to us */
struct sockaddr_in serv; /* socket info about our server */
socklen_t socksize = sizeof(struct sockaddr_in);
memset(&serv, 0, sizeof(serv)); /* zero the struct before filling the fields */
serv.sin_family = AF_INET; /* set the type of connection to TCP/IP */
serv.sin_addr.s_addr = htonl(INADDR_ANY); /* set our address to any interface */
serv.sin_port = htons(PORTNUM); /* set the server port number */
mysocket = socket(AF_INET, SOCK_STREAM, 0);
/* bind serv information to mysocket */
bind(mysocket, (struct sockaddr *)&serv, sizeof(struct sockaddr));
/* start listening, allowing a queue of up to 2 pending connection */
listen(mysocket, 2);
consocket = accept(mysocket, (struct sockaddr *)&dest, &socksize);
if (!bcm2835_init()) return 1;
setpins();
while(consocket)
{
printf("Incoming connection from %s - sending welcome\n", inet_ntoa(dest.sin_addr));
send(consocket, msg, strlen(msg), 0);
while (!qflag && !lflag) {
// Do something when connection is lost: SO_KEEPALIVE?
// if (!send(consocket,testchar, strlen(testchar), 0)) lflag = 1;
recbuf = malloc (MAXRCVLEN+1);
len = recv(consocket, recbuf, MAXRCVLEN, 0);
recbuf[len] = '\0';
if (len > 0) printf("Client sent %s (%d bytes). \n", recbuf, len);
if (recbuf[0] == 'v') forward(); // this function lets our car drive forward
if (recbuf[0] == 'r') backward();// this one backwards ;)
// Leave this loop if the client sends you the quitstring
if (!strcmp (recbuf, quitstring)) qflag = 1;
free(recbuf);
}
if (qflag) break;
listen(mysocket, 1);
consocket = accept(mysocket, (struct sockaddr *)&dest, &socksize);
}
close(consocket);
close(mysocket);
printf("sockets closed\n");
return EXIT_SUCCESS;
}
One line in there
// if (!send(consocket,testchar, strlen(testchar), 0)) lflag = 1;
is our idea to test wether the connection is still up, is this viable?
And this is the client code, thats not in Java yet but in C:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define MAXRCVLEN 500
#define PORTNUM 5298
int main(int argc, char *argv[])
{
char buffer[MAXRCVLEN + 1]; /* +1 so we can add null terminator */
int len, mysocket;
struct sockaddr_in dest;
mysocket = socket(AF_INET, SOCK_STREAM, 0);
memset(&dest, 0, sizeof(dest)); /* zero the struct */
dest.sin_family = AF_INET;
dest.sin_addr.s_addr = inet_addr("192.168.42.1"); /* set destination IP number */
dest.sin_port = htons(PORTNUM); /* set destination port number */
do {
connect(mysocket, (struct sockaddr *)&dest, sizeof(struct sockaddr));
len = recv(mysocket, buffer, MAXRCVLEN, 0);
}while(len < 0);
/* We have to null terminate the received data ourselves */
buffer[len] = '\0';
// Received
printf("Received %s (%d bytes).\n", buffer, len);
// send:
char msg[] = " ";
do{
scanf("%s",msg);
printf("Sending Msg to %s \n", inet_ntoa(dest.sin_addr));
send( mysocket, msg, strlen(msg),0);
}while (strcmp(msg,"quit"));
close(mysocket);
return EXIT_SUCCESS;
}
Any ideas what we did wrong?
Thanks in advance!
Unless what you actually, really want to learn is low-level berkeley socket manipulation, I'd suggest you look at libevent or a similar library.
The structure of your main loop is a little unusual. You can clearly only handle one connection at a time, and you don't cope well with any connection attempts that happened while you were servicing a previous connection.
bind(mysocket, (struct sockaddr *)&serv, sizeof(struct sockaddr));
bind can fail, e.g. if another process has recently had the socket open and the OS hasn't finished cleaning up use of the port. You can change this behavior, but you should still check, from die.net's bind manpage
Return Value
On success, zero is returned. On error, -1 is returned, and errno is set appropriately.
so
if(bind(mysocket, (struct sockaddr *)&serv, sizeof(struct sockaddr))) {
perror("bind failed");
exit(1);
}
listen() only needs to be called once, but also needs to be checked
if(listen(mysocket, 2)) {
perror("listen failed");
exit(1);
}
after this, if you are content to do the single-service approach, then you can do the following:
mysocket = socket(AF_INET, SOCK_STREAM, 0);
if(mysocket < 0) {
perror("socket failed");
exit(1);
}
if(bind(mysocket, (struct sockaddr *)&serv, sizeof(struct sockaddr))) {
perror("bind failed");
exit(1);
}
if(listen(mysocket, 2)) {
perror("listen failed");
exit(1);
}
for (;;) {
consocket = accept(mysocket, (struct sockaddr *)&dest, &socksize);
if(consocket < 0) // might return if the connection has already gone away.
continue;
if (!sendGreeting(consocket)) {
// sendGreeting should return -1 if it was unable to send, 0 if successful
while (!readLoop(consocket, recvBuf, MAXRCVLEN))
;
}
close(consocket);
}
readLoop would then be something like:
int readLoop(int socket, char* buffer, size_t bufSize) {
int len = recv(socket, buffer, bufSize);
if (len > 0)
return processBuffer(socket, buffer, len);
if (len < 0 && (errno == EINTR || errno == EAGAIN))
return 0; // do-over
return -1;
}
make sure that processBuffer also returns 0 or -1 accordingly.
As I mentioned above, there are still problems with this approach, but it's not my intent here to teach you everything you need to know about sockets in one pass :) If you want to further develop your socket knowledge, your next stop should be learning about select or poll with non-blocking sockets so that you can host multiple sockets and service them as they become active.
Generally, you should use tcpdump/wireshark to see what packets are seen by you Rpi, and strace to see what your program does. My first guess about your connections sometimes not working would be loss of packets. By using wired LAN (Ethernet), you could rule this possibility out.
But the example server code that you're using is a rather bad example. Even if you only want to accept a single client connection at a time, your server should not use blocking waits for any remote message. You should read about using non-blocking I/O, select or poll, and look at examples using these. Also, please read about SO_REUSEADDR, you probably need that one in your server as well.
This line code
char msg[] = " ";
do{
scanf("%s",msg);
will fail miserably if the number of bytes scanned in is larger then 1 character, as msg provides exactly two bytes (from which one is always used as 0-terminator). Feeding more would write out of the bounds of msg and doing so will provoke undefined behaviuor.
To fix this providing at least a minimum of 255 characters to so:
char msg[256] = "";
do{
scanf("%255s",msg);
I'm just starting out on networking programming in c. I followed a simple tutorial to create a server which accepts a connection and prints out the message sent from the client.
the client takes an argument as the address of the server.
I'm not sure how to specify the address of the server? Is it my machine name?
I'm running the server in one terminal and trying to connect from another. Thanks for any help :)
here's the server code
`#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include<stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
#define BUFLEN 1500
int fd;
ssize_t i;
ssize_t rcount;
char buf[BUFLEN];
printf("test1");
fd = socket (AF_INET,SOCK_STREAM,0);
if (fd == -1){
printf("Oh dear, something went wrong with read()! %s\n", strerror(errno));
}
struct sockaddr_in addr;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_family = AF_INET;
addr.sin_port = htons(500);
if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
printf("cannot bind socket");
}
if (listen(fd, 20) == -1) {
printf("unable to listen");
}
int connfd;
struct sockaddr_in cliaddr;
socklen_t cliaddrlen = sizeof(cliaddr);
connfd = accept(fd, (struct sockaddr *) &cliaddr, &cliaddrlen);
if (connfd == -1) {
printf("unable to accept");
}
rcount = read(fd, buf, BUFLEN);
if (rcount == -1) {
// Error has occurred
}
for (i = 0; i < rcount; i++) {
printf("%c", buf[i]);
}
}`
printf("test1");
You should add "\n" (newline char) at the end of printed string, so that it prints immediately. Without "\n", printf() buffers its output, and you don't see them.
addr.sin_port = htons(500);
Ports 0 - 1023 are called "well known port" and reserved to the system (root). You should use port 1024 or greater for a test program like this. Changing it from 500 to 1500 (for example) binds successfully.
(You don't see the error message "cannot bind socket" because it has no "\n", as I said above.)
rcount = read(fd, buf, BUFLEN);
You should read from connfd, instead of fd. With these changes, it worked for me.
(I used "telnet localhost 1500" as a client.)
im making a simple TCP client-server in c and im trying to send a message from the client to the server, but im having some problems with it.
The server does send the message (integer value > 0) but the client is unable to receive it (integer value > 0)
here is the code:
Client
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdio.h>
int main()
{
int s_id;
char *msg = "hello";
struct sockaddr_in serv_addr;
s_id = socket (AF_INET, SOCK_STREAM, 0);
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons (1156);
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
connect(s_id,(struct sockaddr *) &serv_addr, sizeof (struct sockaddr));
int r = recv (s_id, (char *) msg, 9, 0);
printf("%d \n", r );
printf("%s \n", msg );
return 0;
}
Server:
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
int main()
{
int s_id;
char *msg = "connected";
struct sockaddr_in my_addr, remote_addr;
s_id = socket (PF_INET,SOCK_STREAM,0);
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(1156);
my_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
bind(s_id,(struct sockaddr *) &my_addr, sizeof(struct sockaddr));
listen (s_id,5);
int size = sizeof (struct sockaddr_in);
int new_sd = accept (s_id, (struct sockaddr *) &remote_addr, &size);
int s= send(new_sd, (void *)msg, 9, 0);
printf("%d \n", s );
return 0;
}
The outputs i get (after first starting the server, and then the client) are
server side: 9
client-side: -1
hello
I am using Ubuntu 11.04 and the gcc compiler.
I hope someone out there can help.
Thank you
Umar
char *msg = "hello";
This is a string literal. It's a constant, and you can't change it.
int r = recv (s_id, (char *) msg, 9, 0);
And there you're trying to write to it.
Change your declaration to:
char msg[20];
memset(msg, 0, sizeof(msg));
If you make that change, your code works as expected.
In C you're going to have to allocate and manage buffers - there's no free lunch :)
Also take note of the other answer from Nikolai N Fetissov - you really should be checking return codes from all the system calls.
You never check for errors after any of the system calls. All of socket(2), connect(2), etc. return -1 on failure, then you can print the error description with, say, perror(3) function. Each system call manual page lists possible errors.
Edit 0:
The real problem is probably what Brian points out - you are trying to receive data into read-only memory on the client. Does it die with a segfault?