--------------------------------------------------------------------------------
unisock.h
--------------------------------------------------------------------------------
#ifndef _UNISOCK_H_
#ifndef _WIN32
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
typedef int SOCKET;
typedef struct sockaddr SOCKADDR;
typedef struct sockaddr_in SOCKADDR_IN;
#define SOCKET_ERROR -1
#define INVALID_SOCKET -1
#define SD_RECEIVE 0x0
#define SD_SEND 0x1
#define SD_BOTH 0x2
#define closesocket(s) close(s)
#endif /* _WIN32 */
#define _UNISOCK_H_
#endif /* _UNISOCK_H_ */
--------------------------------------------------------------------------------
В этом примере мы получили возможность обрабатывать несколько входящих соединений (хотя, если в канале нет данных от клиента, то select ждет 1 секунду; таким образом, мы не можем отправлять данные клиентам чаще, но этого нам в дальнейшем будет достаточно) и не останавливаться на блокирующих вызовах. Интервал в 1 секунду выбран произвольно. Мы можем испытать наш сервер, набрав команду:
telnet localhost 8200
Остановить выполнение сервера можно с помощью Ctrl-C

. Разумеется, в приведенном примере еще многое можно "подрихтовать" (например, можно проверять, доступен ли сокет для записи перед вызовом send или проверять код ошибки accept), но мы объявим серверную часть готовой и перейдем, наконец, к клиенту.
2.3 Клиент.
Программирование клиентских сокетов несколько проще, чем серверных. На клиенте достаточно создать сокет с помощью socket(2) и соединить с удаленной стороной с помощью connect(2). После этого сокет готов к приему и передаче данных. Просто приведем пример.
sockclient.h
--------------------------------------------------------------------------------
#ifndef _SMSCE_H_
#ifdef _WIN32
#include <winsock2.h>
#define socklen_t int
#else
#include "unisock.h"
#include <fcntl.h>
#include <sys/time.h>
#define Sleep(x) usleep((unsigned long )(x * 1000))
#endif
#define _SMSCE_H_
#endif /* _SMSCE_H_ */
--------------------------------------------------------------------------------
sockclient.cpp
--------------------------------------------------------------------------------
#include <iostream>
#include <stdio.h>
#include "sockclient.h"
#define SERVER_ADDR "127.0.0.1" // localhost
#define SERVER_PORT 8200
#define RECVBUFSIZ 4096
using namespace std;
int
main(int argc, char **argv)
{
#ifdef _WIN32
WSADATA WSAData;
// Startup socket library
if (WSAStartup(MAKEWORD(1,1), &WSAData) != 0)
perror("Can't initialize socket library");
#endif
SOCKET soc;
struct sockaddr_in addr;
static char buf[RECVBUFSIZ];
int received;
addr.sin_family = AF_INET;
// Server address
addr.sin_addr.s_addr = inet_addr(SERVER_ADDR);
// Server port
addr.sin_port = htons(SERVER_PORT);
// Creating socket
if ((soc = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
perror("Can't create socket");
return 1; }
// Perform connection
if (connect(soc, (struct sockaddr *) &addr, sizeof(addr)) == SOCKET_ERROR) {
perror("Can't connect");
return 1;
}
cout << "Connection is established" << endl;
// Try to receive greeting.
// Note thar receive is the blocking call
if ((received = recv(soc, buf, RECVBUFSIZ, 0)) != SOCKET_ERROR) {
buf[received] = '\0';
cout << (char *)buf << flush;
}
else {
perror("Receive operation failed");
closesocket(soc);
return 1;
}
// Try to send greeting
if (send(soc, "Hello from client ",
strlen("Connection is established "), 0) == SOCKET_ERROR) {
perror("Hello from client ");
closesocket(soc);
return 1;
}
closesocket(soc);
return 0;
}