Вы находитесь на странице: 1из 5

Creating a socket

The first thing to do is to create a socket which you can then manipulate in many ways. To
create a socket, you can use the socket() function.

Includes:

#include <sys/types.h>
#include <sys/socket.h>

Syntax:

int socket(int af, int type, int protocol);

C source:

int socket_desc;

socket_desc=socket(AF_INET,SOCK_STREAM,0);
if (socket_desc==-1)
perror("Create socket");

socket() returns a socket descriptor which can be used in other network commands. This
will create a socket which uses DARPA Internet addresses, and the method of connection is
a byte streamwhich is similar to a pipe. An alternative to byte streams is a datagram but
this tutorial does not cover them.
With servers, the first socket created is often known as a " master socket". Before the
socket can send or receive data, it must be connected to another socket. If acting as a
master socket, it must be bound to a port number so that clients can know where to "find"
the socket and connect to it.
If successful, socket() returns a valid socket descriptor; otherwise it returns -1 and sets
errno to indicate the error. perror() or strerror() can be used to turn the errno value into a
human readable string.

Binding a socket to a port


To set up a master socket, you need to bind the socket descriptor to a in many ways. To
create a socket, you can use the socket() function as described above in Creating a
socket.

Includes:

#include <sys/socket.h>
#include <netinet/in.h>

Syntax:

int bind(int s, struct sockaddr *addr, int addrlen);


C source:

struct sockaddr_in address;

/* type of socket created in socket() */


address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
/* 7000 is the port to use for connections */
address.sin_port = htons(7000);
/* bind the socket to the port specified above */
bind(socket_desc,(struct sockaddr *)&address,sizeof(address));

If successful, bind() returns 0; otherwise it returns -1 and sets errno to indicate the error.
The port specified in the source code above (port 7000) is where the server can be
connected to. To test this, compile the program `sockbind' from the source code directory
and run it. While it is running, type:

telnet localhost 7000

and you should get

Trying...

for a few seconds and then

telnet: Unable to connect to remote host: Connection refused

as the server program finishes. This indicates the server was ok. If the connection is refused
immediately, there is probably a problem with the server.

Listening for connections


Before any connections can be accepted, the socket must be told to listen for connections
and also the maximum number of pending connections using listen()

Includes:

#include <sys/socket.h>

Syntax:

int listen(int s, int backlog);

C source:

listen(socket_desc,3);

the above line specifies that there can be up to 3 connections pending. If a connection
request arrives when there are already 3 connections pending, the client receives a timeout
error.
listen() applies only to unconnected sockets of type SOCK_STREAM. If the socket has not
been bound to a local port before listen() is invoked, the system automatically binds a local
port for the socket to listen on.
If successful, listen() returns 0; otherwise it returns -1 and sets errno to indicate the error.

Accepting a connection
To actually tell the server to accept a connection, you have to use the function accept()

Includes:

#include <sys/socket.h>

Syntax:

int accept(int s, struct sockaddr *addr, int *addrlen);

C source:

int addrlen;
struct sockaddr_in address;

addrlen = sizeof(struct sockaddr_in);


new_socket = accept(socket_desc, (struct sockaddr *)&address, &addrlen);
if (new_socket<0)
perror("Accept connection");

accept() is used with connection based sockets such as streams. The parameters are the
socket descriptor of the master socket followed by a sockaddr_in structure and the size of
the structure. If successful, accept() returns a positive integer which is the socket descriptor
for the accepted socket. If an error occurs, -1 is returned and errno is set to indicate the
cause.

There is some example source code in the directory, the program to compile is called
`accept' While it is running, type:

telnet localhost 7000

and you should get

Trying...
Connected to localhost.
Escape character is '^]'.

and then 10 seconds later, it should close the connection. Once again, if the connection is
refused immediately, there is probably a problem with the server.

Closing connections
Probably one of the easiest things to do with a socket, is close it. This is done using close()

Includes:

#include <unistd.h>

Syntax:

int close(int sockdes);

C source:

close(new_socket);

close() closes the socket descriptor indicated by sockdes.


Upon successful completion, close() returns a value of 0; otherwise, it returns -1 and sets
errno to indicate the error.

Sending data to a connection


Accepting a connection would not be any use without the means to send or receive data.
Send without receive could be used for an information server which always returns a fixed
message.

Includes:

#include <sys/socket.h>
#include <string.h>

Syntax:

int send(int s, const void *msg, int len, int flags);

C source:

char *message="This is a message to send\n\r";

send(new_socket,message,strlen(message),0);

The message should have \n\r instead of just \n or \r because otherwise the text which
appears on some clients may seem strange. e.g the text with just a \n would appear as
follows:

This is a message
and this is the second line
and the third.

instead of:
This is a message
and this is the second line
and the third.

send() is used to transmit a message to another socket and can be used only when the
socket is in a connected state. The socket descriptor that specifies the socket on which the
message will be sent is 's' in the syntax above. 'msg' points to the buffer containing the
message and the length of the message is given by len, in bytes.
The supported values for flags are zero, or MSG_OOB (to send out-of-band data) - a write()
call made to a socket behaves in exactly the same way as send() with flags set to zero.
Upon successful completion, send() returns the number of bytes sent. Otherwise, it returns
-1 and sets errno to indicate a locally-detected error. The `accept' program is modified to
send a welcome message to the connection before it closes the socket. To see how this is
done, have a look at the source code for the program `send'.

Receiving data from a connection


Accepting a connection would not be any use without the means to send or receive data.
Receive only could be used as a data collection method.

Includes:

#include <sys/socket.h>

Syntax:

int recv(int s, void *msg, int len, int flags);

C source:

int bufsize=1024; /* a 1K buffer */


char *buffer=malloc(bufsize);

recv(new_socket,buffer,bufsize,0);

The flags parameter can be set to MSG_PEEK, MSG_OOB, both, or zero. If it is set to
MSG_PEEK, any data returned to the user still is treated as if it had not been read, i.e the
next recv() re-reads the same data.
A read() call made to a socket behaves in exactly the same way as a recv() with flags set to
zero.
If successful, recv() returns the number of bytes received, otherwise, it returns -1 and sets
errno to indicate the error. recv() returns 0 if the socket is blocking and the connection to
the remote node failed.

Вам также может понравиться