Berkeley Socket API – Creating a TCP/IP client in C

Programming Languages

C

API

Berkeley Socket API

Data Structure used to store socked details

1
2
3
4
5
6
7
struct sockaddr_in6 {
    u_char      sin6_len;   // length of this structure
    u_char      sin6_family;    // AF_INET6
    u_int16m_t  sin6_port;  // Transport layer port #
    u_int32m_t  sin6_flowinfo;  // IPv6 flow information
    struct in6_addr sin6_addr;  // IPv6 address
};

Filling the socket local address

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Declare the vars to use
struct sockaddr_in6 localaddress, remoteaddress;
// Fill the structures with zero's
memset(&localaddress,0,sizeof(localaddress));
memset(&remoteaddress,0,sizeof(remoteaddress));
// Client socket details
// Listen on any ipv6 address
localaddress.sin6_addr = in6addr_any;
// Address Family AF_INET6 is required
localaddress.sin6_family = AF_INET6;
// A client usually runs on a random port, the server has a static port
localaddress.sin6_port = 0;
// Server socket details
// Fill remote.sin6_addr with the network address
inet_pton(AF_INET6,"2001:41d0:1:f574::1111", &remote.sin6_addr);
// Address Family AF_INET6 is required
remote.sin6_family = AF_INET6;
// Server port
remote.sin6_port = htons(8000);

Creating the socket

1
int socket(int domain, int type, int protocol);

domain

AF_UNIX – UNIX internal protocols
AF_INET – ARPA Internet protocols
AF_ISO – ISO protocols
AF_NS – Xerox Network Systems protocols
AF_IMPLINK – IMP host at IMP link layer

Type

SOCK_STREAM – provides sequenced, reliable, two-way connection based byte streams
SOCK_DGRAM – connectionless, unreliable messages of a fixed (typically small) maximum length
SOCK_RAW – sockets provide access to internal network protocols and interfaces
SOCK_SEQPACKET – provide a sequenced, reliable, two-way connection-based data transmission path for datagrams of fixed maximum length
SOCK_RDM – Not implemented

Returns

0 – Error
1+ – Socket descriptor

Bind the socket

1
int bind(int socket, const struct sockaddr *address, socklen_t address_len);

socket – Socket descriptor
address – Socket address (address, port, family…)
address_len – Structure address size

Connect to remote socket

1
int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);

socket – Socket descriptor
address – Socket address (address, port, family…)
address_len – Structure address size

Returns

0 – OK
-1 – Error

Read and write from a socket

It works exactly like when we’re reading from a file, pipe, etc.

Read from socket

1
read(sockd, &buffer, 100);

Write to socket

1
write(sockd, &buffer, strlen(buffer));

Client code revealed

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
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <unistd.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
 
void newConnectionHandler(int sockd){
    char buffer[100] = {'t', 'e', 's', 't', '\0'};
 
    if(write(sockd, &buffer, strlen(buffer)) < 1)
        perror("Unable to write on socket");
    if(read(sockd, &buffer, 100) < 0)
        perror("Unable to read from socket");
 
    printf("Received: %s\n", buffer);
}
 
int main(int argc, char *argv[])
{
    int sockd,newsockd,tmpint;
    struct sockaddr_in6 localaddress,remoteaddress;
    fd_set descriptorslist;
    struct timeval timeout;
 
    // Client address
    memset(&localaddress,0,sizeof(localaddress));
    localaddress.sin6_addr = in6addr_any;
    localaddress.sin6_family = AF_INET6;
    localaddress.sin6_port = 0;
 
    // Server address
    memset(&remoteaddress,0,sizeof(remoteaddress));
    inet_pton(AF_INET6, "2001:41d0:1:f574::1111", &remoteaddress.sin6_addr);
    remoteaddress.sin6_family = AF_INET6;
    remoteaddress.sin6_port = htons(8000);
 
    // Create the socket
    if((sockd = socket(AF_INET6, SOCK_STREAM,0))<1){
        perror("Unable to create socket");
        return 1;
    }
 
    // Bind socket sockfd on localaddress
    if(bind(sockd, (struct sockaddr *)&localaddress, sizeof(localaddress)) != 0){
        perror("Unable to bind socket");
        return 1;
    }
 
    tmpint = sizeof(remoteaddress);
    if(connect(sockd,(struct sockaddr *)&remoteaddress, tmpint) == -1){
        perror("Unable to connect");
        return 1;
    }
 
    newConnectionHandler(sockd);
}
 

http://www.silviosilva.com/2009/07/15/berkeley-socket-api-creating-a-tcpip-server-in-c/

原文地址:https://www.cnblogs.com/westfly/p/2173278.html