Har gjort en hel del socket-programmering i C. Första frågan är: är målet att göra socket-programmering i C/C++ eller är målet att lära dig lite om nätverksprogrammering i största allmänhet genom att t.ex. göra en chat-server/klient?
Om det är det senare så är ett tips att titta på Go som är otroligt enkelt att göra nätverksprogrammering i, mer specifikt är det klart enklare att göra väldigt skalbara nätverksprogram i Go än vad det är i C++, Java eller C#.
Men om du verkligen vill programmera i C/C++ så kommer några exempel.
Öppna en UDP/TCP socket, automatiskt hantera fallet IPv4/IPv6
/*
* host - address or name of the remote node, ex "127.0.0.1", "::1" or "localhost"
* port - name or number of the service to connect to, ex "80", "www", "html"
* sock_type - SOCK_DGRAM to use UDP, SOCK_STREAM to use TCP
*/
int open_socket(const char *host, const char *port, int sock_type)
{
struct addrinfo *r, hints;
int ai_err;
int sock;
memset(&hints, 0, sizeof(hints));
hints.ai_socktype = sock_type;
ai_err = getaddrinfo(host, port, &hints, &r);
if (ai_err != 0)
{
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(ai_err));
exit(EXIT_FAILURE);
}
sock = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
if (sock < 0)
{
perror("socket");
exit(EXIT_FAILURE);
}
if (connect(sock, r->ai_addr, r->ai_addrlen) < 0)
{
perror("connect");
exit(EXIT_FAILURE);
}
freeaddrinfo(r);
return sock;
}
Bara som referens, här är samma kod i Go
func open_sock(host string, port string, sock_type string) Conn {
if conn, err := net.Dial(sock_type, net.JoinHostPort(host, port)); err != nil {
panic(err)
}
return conn
}
Och här är ett komplett exempel på både en "server" och "klient" i samma program, går att bygga direkt i CygWin (på Windows), Linux och OSX
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdio.h>
void panic(const char *msg)
{
perror(msg);
exit(EXIT_FAILURE);
}
int main(int argc, char *argv[])
{
int server_sock;
int listen_sock;
int client_sock;
char msg[] = "Hello world";
char rmsg[sizeof msg];
struct addrinfo *r;
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_socktype = SOCK_STREAM;
getaddrinfo("localhost", "12345", &hints, &r);
listen_sock = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
if (listen_sock < 0)
panic("socket");
/* Assign the socket to port "12345" and address "localhost" */
if (bind(listen_sock, r->ai_addr, r->ai_addrlen) < 0)
panic("bind");
/* Start listening for incoming requests */
if (listen(listen_sock, 0) < 0)
panic("listen");
client_sock = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
if (client_sock < 0)
panic("socket");
/* Connect to the "server", i.e. "localhost" at port "12345" */
if (connect(client_sock, r->ai_addr, r->ai_addrlen) < 0)
panic("connect");
freeaddrinfo(r);
/* Accept connection */
server_sock = accept(listen_sock, NULL, NULL);
if (server_sock < 0)
panic("accept");
/* Does not want to accept any more connections */
close(listen_sock);
if (send(server_sock, msg, sizeof msg, 0) < 0)
panic("send");
if (recv(client_sock, &rmsg, sizeof rmsg, 0) < 0)
panic("recv");
printf("Server says: %s\n", rmsg);
close(server_sock);
close(client_sock);
}