A little help with a basic sockets program

Pages: 12
Hello, I am looking to write a simple program where you have a client that sends a message to a server and the server saves the message as a variable and then prints that variable. I have already written both the client and the server but for some reason it isn't working as expected. If someone could help me fix my code and explain to me what was wrong that would be great,
thank you

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
//client
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <iostream.h>
#include <string.h>
#include <istream.h>
using namespace std;

int sock_con(char remoteip[128], char port[128])

{

    struct addrinfo hints, *res;
    int sockfd, con, die;

        int sock;
        int err;



        memset(&hints, 0, sizeof hints);
        hints.ai_family = AF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;
        getaddrinfo(remoteip, port, &hints, &res);

        // make a socket:
        sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);

        if(sockfd < 0)
            {cout << "Error on socket level\n";
            return -1;
            }


        // connect
        con = connect(sockfd, res->ai_addr, res->ai_addrlen);
            if(con < 0)
                {cout << "Error on connection level\n";
                return -1;
                }




        return sockfd;


}

int main()
{
  //Initialize connection
    char ip[128], portn[128];
    int sockid;
    cout << "Enter target IP: \n";
    cin >> ip;
    cout << "\nEnter target port: \n";
    cin >> portn;


    sockid = sock_con(ip, portn);

        if (sockid == -1)
        {
            cout << "\nError\n";
            return -1;
        }

        char *msg;
        cout << "Enter Message:\n";
        cin >> msg;

        int len, bytes_sent;
        len = strlen(msg);
        bytes_sent = send(sockid, msg, len, 0);

        if (bytes_sent <= 0)
        {
            cout << "\nIfail! No data was sent\n";
            if(bytes_sent<0)
            {
                cout << "\nError\n" << errno;
            }


            return -1;

        }

    cout << "\nComplete\n";
    return 0;

}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
//server
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <iostream.h>
#include <string.h>
#include <istream.h>
#include <string.h>
using namespace std;

 int main()
 {

        struct sockaddr_storage their_addr;
        socklen_t addr_size;
        struct addrinfo hints, *res;
        int sockfd, new_fd, con, die, sock, err, recv_bytes;




        memset(&hints, 0, sizeof hints);
        hints.ai_family = AF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;
        hints.ai_flags = AI_PASSIVE;
        getaddrinfo(NULL, "3490", &hints, &res);

        // make a socket:
        sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);

        if(sockfd < 0)
            {cout << "Error on socket level\n";
            return -1;
            }

        bind(sockfd, res->ai_addr, res->ai_addrlen);


                        while(1)
                        {


                             listen(sockfd, 10);
                            addr_size = sizeof their_addr;
                            new_fd = accept(sockfd, (struct sockaddr         *)&their_addr, &addr_size);
                                if(new_fd == -1)
                                {
                                    cout << "error accepting connection";
                                    continue;
                                }

                            cout << new_fd;

                            char buf[256];
                            int len;

                          recv_bytes = recv( new_fd, buf,  len, 0);
                          if(recv_bytes < len) {cout << "error recieving data, less bytes recieved than sent";}
                            cout << buf;
                        }
             die = shutdown(sockfd,2);

            if(die < 0)
                {cout << "Failed to shutdown\n";
                return -1;
                }
            if(die == 0){cout << "Success!\n";}


        return  new_fd;

 }
Any one?
In your server code it looks like you have not set the int variable len to any value prior to using it as an argument to the recv() function.

I.E.

1
2
int len;
recv_bytes = recv( new_fd, buf,  len, 0);


Since the recv() function uses the third int argument to determine how many bytes of data is is going to try and read from the socket I imagine you are getting some very strange results.

Can't see any other faults though.
Last edited on
First off thank you for your help. I set "int len = 256;" to see what would happen and the server program remains quite... There is neither no output nor error on either side.. Any idea?
Update:
I am getting a wierd runtime error when using xcode (vs CodeBlocks which i was using before). On the line cin >> msg; in the client program it says
thread 1: program received signal: "EXC_BAD_ACCESS"
. I haven't an idea what this means.
First, I'm not an ace programmer in C++ yet. I think - but am not sure - that this may be a problem
I saw years ago in a "C" program which had a "funny" problem. I think the statement "return
sockfd" is acting as it was instructed to do. However, the variable sockfd is declared as a
dynamic - not a static - variable. As a quickie check, edit your declaration statement as follows :

static int sockfd;

Then compile the code and see if it runs OK. If it does, read up on the difference between
static and dynamic variables.

As said, I'm not an ace. I hope this helps.
No change. I dont think it would matter if it were const/static or not, there is nothing that would change it. Any other advice?
try change char *msg to char msg[256]
So i did what Danilo said and it appears that the client side works flawlessly. However the server side now fails after the message is sent. I had to change "cout << buff;" to:
1
2
3
4
5
6
int i;
            for (i = 0; buf != NULL; i++)
            {
            cout << &buf[i];
            }
        cout << i;


and i am getting:
thread 1: program received signal: "EXC_BAD_ACCESS"

on the " cout << &buf[i];" line


the server had to be for (i = 0; buf[i] != NULL; i++)

but now it isnt displaying anything
Last edited on
closed account (DSLq5Di1)
1
2
3
4
5
6
7
//server
...

        char buf[256];
        int len;

        recv_bytes = recv( new_fd, buf,  len, 0); // what does len = ? 
someone already said that and i updated it to "int len = 256;"

----

its getting stuck on something im not sure what. Here is the current server code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <iostream.h>
#include <fstream>
#include <string.h>
#include <istream.h>
#include <string.h>
using namespace std;

int main()
{
    
    struct sockaddr_storage their_addr;
    socklen_t addr_size;
    struct addrinfo hints, *res;
    int die, recv_bytes;
    long int new_fd;
    
    
    
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;
    getaddrinfo(NULL, "3490", &hints, &res);
    
    const int sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
    
    if(sockfd < 0)
    {cout << "Error on socket level\n";
        return -1;
    }
    
    bind(sockfd, res->ai_addr, res->ai_addrlen);
    
    
    while(1)
    {
        
        
        listen(sockfd, 10);
        addr_size = sizeof their_addr;
        new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &addr_size);
        if(new_fd == -1)
        {
            cout << "error accepting connection";
            continue;
        }
        
        cout << new_fd;
        
        char buf[256];
        long int len = 256;
        
        recv_bytes = recv( new_fd, buf,  len, 0);
        if(recv_bytes < len) {cout << "error recieving data, less bytes recieved than sent";}

        
        
       int i;
            for (i = 0; buf[i] != NULL; i++)
            {
            cout << &buf[i];
            }
        cout << i;
        
    }
    die = shutdown(sockfd,2);
    
    if(die < 0)
    {cout << "Failed to shutdown\n";
        return -1;
    }
    if(die == 0){cout << "Success!\n";}
    
    
    return  new_fd;
    
}
Last edited on
closed account (DSLq5Di1)
Eep sorry I must have missed that!
in the server try it:
recv_bytes = recv( new_fd, &buf, len, 0);

for (i = 0; i <=256; i++)
{
cout << &buf[i];
}
and in the client, after cin >> msg; fflush(stdin);
closed account (DSLq5Di1)
Tested your client/server code this evening, other than a few changes so it would run under windows, I had no problem sending text from client to server.

Regarding your server output, you don't need to iterate through the buffer.. simply cout << buf;. You'll want to include the null terminator from the client side len = strlen(msg) + 1;, or null terminate from the server side with buf[recv_bytes] = '\0'; before output.
it's wierd.. cause my server doesn't do a thing. Once its running it doesnt display anything. Sloppy9: you said u got it working? is there something i could be missing?

___

very strange:
I added
1
2
3
4
5
6
7
8
9
      int test=1;
        if (test==2)
        {
            cout << "good";
        }else
        {
            cout << "first loop";
        }
        test=2;


to the beginning of the while loop in the server code and it didn't display anything. I have no idea why
Last edited on
closed account (DSLq5Di1)
Mmm.. if there is no output at the server, perhaps the client is unable to connect? have you tested the client/server running on the one machine?
Well i have tried a bunch of things.. but if u look at my preivous post its really wierd that it doesn't post either good or first loop
closed account (DSLq5Di1)
The code you added, is that before or after the call to accept? blocking is the default behaviour for sockets, once you call accept() the function will not return until there is a connection.
no it is before. It is directly after while(1) {


is it possible for it to get stuck on bind?
Last edited on
Pages: 12