Skip to content
Snippets Groups Projects
Commit e7b2a0d2 authored by Nicolas Leclercq's avatar Nicolas Leclercq
Browse files

added new socket sample

parent 944fe6a3
No related branches found
No related tags found
No related merge requests found
Showing
with 1093 additions and 0 deletions
#==============================================================================
# Makefile to generate the YAT Test - NL - SOLEIL
#==============================================================================
#==============================================================================
# INCLUDE DIRS
#==============================================================================
INCLUDE_DIRS = -I. -I../../../include
#==============================================================================
# LIB DIRS
#==============================================================================
LIB_DIRS = -L../../../src/.libs
#==============================================================================
# SRC FILE NAME
#===============================================================================
SRC = binary_protocol_client.o
#==============================================================================
# BINARY NAME
#===============================================================================
BIN = binaryprotocolclient
#==============================================================================
# COMP$(CC)ILER/LINKER OPTIONS for GNU/LINUX
#==============================================================================
CC=g++
#------------------------------------------------------------------------------
CFLAGS = -pipe -O2 -W -g
#------------------------------------------------------------------------------
LD=gcc
#------------------------------------------------------------------------------
LDFLAGS =
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# LIBS
#------------------------------------------------------------------------------
LIBS = -lyat -lpthread -lstdc++ -ldl
#------------------------------------------------------------------------------
# OBJS FILES
#------------------------------------------------------------------------------
SRC_OBJS = ./src/$(SRC)
#------------------------------------------------------------------------------
# RULE for .cpp files
#------------------------------------------------------------------------------
.SUFFIXES: .o .cpp
.cpp.o:
$(CC) $(CFLAGS) $(INCLUDE_DIRS) -c -o $@ $<
#------------------------------------------------------------------------------
# RULE: all
#------------------------------------------------------------------------------
all: build
#------------------------------------------------------------------------------
# RULE: build
#------------------------------------------------------------------------------
build: $(SRC_OBJS)
$(LD) -o $(BIN) $(LDFLAGS) $(SRC_OBJS) $(LIB_DIRS) $(LIBS)
#------------------------------------------------------------------------------
# RULE: clean
#------------------------------------------------------------------------------
clean:
rm -f ./src/*.o
rm -f ./src/*~
rm -f ./$(BIN)
/*!
* \file
* \brief A yat::BitsStream example.
* \author N. Leclercq - Synchrotron SOLEIL
*/
#include <iostream>
#include <yat/bitsstream/Endianness.h>
#include <yat/threading/Thread.h>
#include <yat/network/ClientSocket.h>
#define SERVER_PORT 5001
const unsigned char cmds[] =
{
0,
1,
2,
3
};
enum
{
CMD_0 = 0x0,
CMD_1 = 0x1,
CMD_2 = 0x2,
CMD_3 = 0x3
};
const size_t MAX_ERROR_LENGTH = 256;
const unsigned char INVALID_CMD = 0xFF;
typedef unsigned char CmdIdentifier;
typedef unsigned long CmdDataSize;
typedef unsigned long CmdDataLength;
typedef unsigned char * CmdData;
typedef char CmdStatus;
const char CMD_ERROR = -1;
const char CMD_NO_ERROR = 0;
const CmdDataSize CMD_HEADER_SIZE = sizeof(CmdIdentifier)
+ sizeof(CmdDataSize)
+ sizeof(CmdDataLength);
typedef struct
{
CmdIdentifier id; //- cmd identifier
CmdStatus st; //- cmd status: CMD_ERROR or CMD_NO_ERROR
CmdDataSize ds; //- reply size in bytes (could be the size or an error string in case <st> is NOT set to CMD_NO_ERROR)
CmdDataLength dl; //- the number of elements <CmdData> - each element has a size of <ds>/<dl> bytes
CmdData db; //- reply data size in bytes (could be an error string in case <st> is NOT set to CMD_NO_ERROR)
} CmdReply;
//-----------------------------------------------------------------------------
// MAIN
//-----------------------------------------------------------------------------
int main (int argc, char* argv[])
{
try
{
//- yat internal cooking
yat::Socket::init();
//- instanciating the Socket (default protocol is yat::Socket::TCP_PROTOCOL)
std::cout << "Instanciating the Client Socket" << std::endl;
yat::ClientSocket sock;
//- set some socket option
std::cout << "Setting sock options" << std::endl;
sock.set_blocking_mode();
//- network address
std::cout << "Instanciating network address" << std::endl;
yat::Address addr("localhost", SERVER_PORT);
//- connect to addr
std::cout << "Connecting to peer..." << std::endl;
sock.connect(addr);
size_t n = 2;
yat::uint32 dd_length = 65;
yat::Buffer<double> dd(dd_length);
for (size_t i = 0; i < dd_length; i++)
dd[i] = static_cast<double>(i);
yat::Socket::Data binary_out;
CmdDataSize ds = dd_length * sizeof(double);
binary_out.capacity(CMD_HEADER_SIZE + ds);
binary_out.force_length(binary_out.capacity());
yat::Socket::Data binary_in(32 * 1024, true);
do
{
char * p = binary_out.base();
size_t offset = 0;
memcpy(p + offset, &cmds[0], sizeof(CmdIdentifier));
offset += sizeof(CmdIdentifier);
memcpy(p + offset, &ds, sizeof(CmdDataSize));
offset += sizeof(CmdDataSize);
memcpy(p + offset, &dd_length, sizeof(CmdDataLength));
offset += sizeof(CmdDataLength);
memcpy(p + offset, dd.base(), ds);
std::cout << "Sending " << binary_out.size() << " bytes to the server..." << std::endl;
sock << binary_out;
std::cout << "Waiting for reply from the server..." << std::endl;
sock >> binary_in;
CmdReply reply;
reply.id = *((CmdIdentifier*)(binary_in.base() + 0));
reply.st = *((CmdStatus*)(binary_in.base() + 1));
reply.ds = *((CmdDataSize*)(binary_in.base() + 2));
reply.dl = *((CmdDataLength*)(binary_in.base() + 6));
reply.db = (CmdData)(binary_in.base() + 10);
std::cout << "reply for cmd-"
<< (unsigned int)reply.id
<< " is "
<< ( reply.st == CMD_ERROR ? "ERROR" : "NO-ERROR")
<< " + "
<< reply.ds
<< " bytes of data representing "
<< reply.dl
<< " elements of "
<< reply.ds / reply.dl
<< " bytes each"
<< std::endl;
--n;
}
while (n);
//- disconnect from peer
std::cout << "Disconnecting from peer..." << std::endl;
sock.disconnect();
//- yat internal cooking
yat::Socket::terminate();
}
catch (const yat::SocketException & se)
{
std::cout << "*** yat::SocketException caught ***" << std::endl;
for (size_t err = 0; err < se.errors.size(); err++)
{
std::cout << "Err-" << err << "::reason..." << se.errors[err].reason << std::endl;
std::cout << "Err-" << err << "::desc....." << se.errors[err].desc << std::endl;
std::cout << "Err-" << err << "::origin..." << se.errors[err].origin << std::endl;
std::cout << "Err-" << err << "::code....." << se.errors[err].code << std::endl;
}
}
catch (...)
{
std::cout << "Unknown exception caught" << std::endl;
}
return 0;
}
#==============================================================================
# Makefile to generate the YAT Test - NL - SOLEIL
#==============================================================================
#==============================================================================
# INCLUDE DIRS
#==============================================================================
INCLUDE_DIRS = -I. -I../../../include
#==============================================================================
# LIB DIRS
#==============================================================================
LIB_DIRS = -L../../../src/.libs
#==============================================================================
# BINARY NAME
#===============================================================================
BIN = binaryprotocolserver
#==============================================================================
# COMP$(CC)ILER/LINKER OPTIONS for GNU/LINUX
#==============================================================================
CC=g++
#------------------------------------------------------------------------------
CFLAGS = -pipe -O2 -W -g
#------------------------------------------------------------------------------
LD=gcc
#------------------------------------------------------------------------------
LDFLAGS =
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# LIBS
#------------------------------------------------------------------------------
LIBS = -lyat -lpthread -lstdc++ -ldl
#------------------------------------------------------------------------------
# OBJS FILES
#------------------------------------------------------------------------------
SRC_OBJS = ./src/binary_protocol_server.o ./src/server.o
#------------------------------------------------------------------------------
# RULE for .cpp files
#------------------------------------------------------------------------------
.SUFFIXES: .o .cpp
.cpp.o:
$(CC) $(CFLAGS) $(INCLUDE_DIRS) -c -o $@ $<
#------------------------------------------------------------------------------
# RULE: all
#------------------------------------------------------------------------------
all: build
#------------------------------------------------------------------------------
# RULE: build
#------------------------------------------------------------------------------
build: $(SRC_OBJS)
$(LD) -o $(BIN) $(LDFLAGS) $(SRC_OBJS) $(LIB_DIRS) $(LIBS)
#------------------------------------------------------------------------------
# RULE: clean
#------------------------------------------------------------------------------
clean:
rm -f ./src/*.o
rm -f ./src/*~
rm -f ./$(BIN)
<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>fr.soleil</groupId>
<artifactId>super-pom-C-CPP-device</artifactId>
<version>RELEASE</version>
</parent>
<groupId>fr.soleil.device</groupId>
<artifactId>yat-client-socket-test-${aol}-${mode}</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>nar</packaging>
<name>ClientSocketTester</name>
<description>a yat::ClientSocket test</description>
<build>
<plugins>
<plugin>
<groupId>org.freehep</groupId>
<artifactId>freehep-nar-plugin</artifactId>
<configuration>
<cpp>
<includePaths>
<includePath>${project.basedir}/src</includePath>
</includePaths>
<options>
<option>-Wno-uninitialized</option>
<option>-Wno-unused-parameter</option>
<option>-Wno-unused-variable</option>
</options>
</cpp>
</configuration>
</plugin>
</plugins>
</build>
<scm>
<connection>${scm.connection.svn.tango-cs}:share/yat</connection>
<developerConnection>${scm.developerConnection.svn.tango-cs}:share/yat</developerConnection>
<url>${scm.url.svn.tango-cs}/share/yat</url>
</scm>
<dependencies>
<dependency>
<groupId>fr.soleil.lib</groupId>
<artifactId>YAT-${aol}-${library}-${mode}</artifactId>
<version>1.7.2</version>
</dependency>
</dependencies>
<developers>
<developer>
<id>leclercq</id>
<name>leclercq</name>
<url>http://controle/</url>
<organization>Synchrotron Soleil</organization>
<organizationUrl>http://www.synchrotron-soleil.fr</organizationUrl>
<roles>
<role>manager</role>
</roles>
<timezone>1</timezone>
</developer>
</developers>
</project>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <iostream>
#include "server.h"
#include "client.h"
enum
{
SOCKET_EVENT_CONNECT = 0x0,
SOCKET_EVENT_DISCONNECT = 0x1,
SOCKET_EVENT_DATA = 0x2
};
enum
{
CMD_0 = 0x0,
CMD_1 = 0x1,
CMD_2 = 0x2,
CMD_3 = 0x3
};
#define PORT 5001
#define MAX_CLIENTS 1
#define BUF_SIZE 128
typedef SOCKET ClientSocket;
typedef int SocketEvent;
typedef unsigned char CmdIdentifier;
typedef unsigned long CmdDataSize;
typedef unsigned long CmdDataLength;
typedef unsigned char * CmdData;
typedef char CmdStatus;
const int kERROR = -1;
const int kNO_ERROR = 0;
const CmdIdentifier INVALID_CMD = 0xFF;
const CmdDataSize CMD_HEADER_SIZE = sizeof(CmdIdentifier)
+ sizeof(CmdDataSize)
+ sizeof(CmdDataLength);
typedef struct
{
ClientSocket cs; //- client socket (for reply)
CmdIdentifier id; //- cmd identifier
CmdDataSize ds; //- cmd data size in bytes
CmdDataSize rd; //- total number of bytes received for the cmd (expecting {CMD_HEADER_SIZE + <ds>} bytes in one or more buffers)
CmdDataLength dl; //- cmd data length in number of elements
CmdData db; //- cmd data buffer (will be reinterpreted by cmd processing function)
} CmdInfo;
//- the current processed cmd (cmds are processed one at a time - means one and only one connected client)
static CmdInfo current_cmd;
//- initializes the cmd info (MUST be called at startup)
static void init_cmd (void);
//- clears the cmd info (in order to be able to process the next one)
static void clear_cmd (void);
//- cmd processor - does the job and sends reply to client
static int process_cmd (void);
//- sends reply to client
static int send_reply_txt (CmdStatus stt, const char * txt);
static int send_reply_data (CmdStatus stt, CmdDataSize nbt, CmdDataLength nbe, unsigned char * buf);
//- simulate SPI board TCP/IP callback
void socket_callback (ClientSocket client_socket,
SocketEvent socket_event,
CmdDataSize num_bytes_from_client,
CmdData client_socket_buffer);
//-----------------------------------------------------------------------
// init_cmd
//-----------------------------------------------------------------------
static void init_cmd (void)
{
//- be sure each byte of <current_cmd> is set to zero at init
memset(&current_cmd, 0, sizeof(CmdInfo));
//- be sure <current_cmd.id> is set to INVALID_CMD
current_cmd.id = INVALID_CMD;
}
//-----------------------------------------------------------------------
// clear_cmd
//-----------------------------------------------------------------------
static void clear_cmd (void)
{
//- release memory (leak otherwise)
if ( current_cmd.db )
{
free(current_cmd.db);
current_cmd.db = 0;
}
//- clear the whole structure
memset(&current_cmd, 0, sizeof(CmdInfo));
//- be sure <current_cmd.id> is set to INVALID_CMD
current_cmd.id = INVALID_CMD;
}
//-----------------------------------------------------------------------
// socket_callback (simulates SPI callback)
//-----------------------------------------------------------------------
void socket_callback (SOCKET client_socket,
int socket_event,
size_t num_bytes_from_client,
char * client_socket_buffer)
{
unsigned long elem_size = 0;
unsigned long n_bytes_to_push = 0;
//- here we simulate the SPI callback
switch ( socket_event )
{
case SOCKET_EVENT_CONNECT:
std::cout << "socket_callback::SOCKET_EVENT_CONNECT" << std::endl;
init_cmd ();
break;
case SOCKET_EVENT_DISCONNECT:
std::cout << "socket_callback::SOCKET_EVENT_DISCONNECT" << std::endl;
clear_cmd ();
break;
default:
break;
}
//- any data to process?
if ( num_bytes_from_client == 0 || client_socket_buffer == 0)
return;
//- offset to data in <buffer>
size_t buffer_offset = 0;
//- are we already processing a cmd? (cmd data can spread over several buffers)
if ( current_cmd.id == INVALID_CMD )
{
//- client socket
current_cmd.cs = client_socket;
//- cmd identifier
current_cmd.id = (CmdIdentifier)client_socket_buffer[0];
//- number of bytes in the cmd data
current_cmd.ds = *((CmdDataSize*)&client_socket_buffer[1]);
//- number of elements in the cmd data
current_cmd.dl = *((CmdDataLength*)&client_socket_buffer[5]);
//- size of each element in cmd data
if ( current_cmd.dl )
elem_size = current_cmd.ds / current_cmd.dl;
else
elem_size = 0;
//- log
std::cout << "processing 'new' cmd-" << (unsigned int)current_cmd.id << std::endl;
std::cout << "expecting " << current_cmd.dl << " elements of " << elem_size << " byte(s) each" << std::endl;
std::cout << "expecting " << current_cmd.ds << " bytes of data (excluding header)" << std::endl;
//- allocate cmd data buffer (will be released/freed by the <clear_cmd> function)
current_cmd.db = (CmdData)::malloc(current_cmd.ds);
//- check allocated memory
if ( ! current_cmd.db )
{
//-TODO: send error to client, but... replying also requires memory allocation so... ????
}
//- clear allocated buffer
memset(current_cmd.db, 0, current_cmd.ds);
//- be sure the 'received data' counter is set to 0 for 'new' cmd
current_cmd.rd = 0;
//- offset to cmd data in socket input <buffer>
buffer_offset = CMD_HEADER_SIZE;
}
std::cout << "processing cmd-"
<< (unsigned int)current_cmd.id
<< " - till now we received "
<< current_cmd.rd
<< " bytes for this cmd"
<< std::endl;
//- push cmd data into cmd buffer...
n_bytes_to_push = current_cmd.ds - current_cmd.rd;
if ( n_bytes_to_push > num_bytes_from_client)
n_bytes_to_push = num_bytes_from_client - buffer_offset;
std::cout << "processing cmd-"
<< (unsigned int)current_cmd.id
<< " - pushing "
<< n_bytes_to_push
<< " bytes into cmd data buffer"
<< std::endl;
memcpy(current_cmd.db + current_cmd.rd,
client_socket_buffer + buffer_offset,
n_bytes_to_push);
//- increment the "received data for the current" counter
current_cmd.rd += n_bytes_to_push;
//- received all expected data for the current cmd?
if ( current_cmd.rd == current_cmd.ds )
{
std::cout << "received expected amount of data for cmd-"
<< (unsigned int)current_cmd.id
<< " - calling cmd processor..."
<< std::endl;
//- call cmd processor (will also send reply to client)
process_cmd();
//- clear the "cmd info" to process next cmd
clear_cmd();
}
}
//-----------------------------------------------------------------------
// process_cmd
//-----------------------------------------------------------------------
static int process_cmd (void)
{
double * p = 0;
std::cout << "processing cmd-" << (unsigned int)current_cmd.id << std::endl;
switch ( current_cmd.id )
{
case CMD_0:
{
p = (double *)current_cmd.db;
std::cout << "processing cmd-"
<< (unsigned int)current_cmd.id
<< " cmd-data["
<< 0
<< "] = "
<< *p
<< std::endl;
std::cout << "processing cmd-"
<< (unsigned int)current_cmd.id
<< " cmd-data["
<< current_cmd.dl - 1
<< "] = "
<< *(p + current_cmd.dl - 1)
<< std::endl;
//- let's say that CMD-0 simply returns the data it received...
send_reply_data(kNO_ERROR, current_cmd.ds, current_cmd.dl, current_cmd.db);
}
break;
default:
break;
}
return kNO_ERROR;
}
//-----------------------------------------------------------------------
// send_reply_txt
//-----------------------------------------------------------------------
static int send_reply_txt (CmdStatus stt, const char * txt)
{
std::cout << "returning txt to client for cmd-"
<< (unsigned int)current_cmd.id
<< ": "
<< txt
<< std::endl;
return send_reply_data(stt, strlen(txt), strlen(txt), (unsigned char*)txt);
}
//-----------------------------------------------------------------------
// send_reply_data
//-----------------------------------------------------------------------
static int send_reply_data (CmdStatus stt, //- status
CmdDataSize nbt, //- num of bytes
CmdDataLength nbe, //- num of elements
CmdData buf) //- data
{
CmdData db = 0;
unsigned long offset = 0;
std::cout << "returning "
<< nbt
<< " bytes of data to client for cmd-"
<< (unsigned int)current_cmd.id
<< std::endl;
size_t bs = sizeof(CmdIdentifier)
+ sizeof(CmdStatus)
+ sizeof(CmdDataSize)
+ sizeof(CmdDataLength)
+ nbt;
db = (CmdData)malloc(bs);
if ( db == 0 )
{
//- error handling goes here...
return kERROR;
}
memset(db, 0, bs);
memcpy(db, &current_cmd.id, sizeof(CmdIdentifier));
offset += sizeof(CmdIdentifier);
memcpy(db + offset, &stt, sizeof(CmdStatus));
offset += sizeof(CmdStatus);
memcpy(db + offset, &nbt, sizeof(CmdDataSize));
offset += sizeof(CmdDataSize);
memcpy(db + offset, &nbe, sizeof(CmdDataLength));
offset += sizeof(CmdDataLength);
memcpy(db + offset, buf, nbt);
int result = kNO_ERROR;
if ( send(current_cmd.cs, db, bs , 0) < 0 )
{
//- oops... error handling goes here...
result = kERROR;
}
//- release allocated memory...
free(db);
return result;
}
//-----------------------------------------------------------------------
int main(int argc, char **argv)
{
init();
app(socket_callback);
end();
return EXIT_SUCCESS;
}
#ifndef CLIENT_H
#define CLIENT_H
#include "server.h"
typedef struct
{
SOCKET sock;
char name[BUF_SIZE];
}Client;
#endif /* guard */
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <iostream>
#include "server.h"
#include "client.h"
void init(void)
{
#ifdef WIN32
WSADATA wsa;
int err = WSAStartup(MAKEWORD(2, 2), &wsa);
if(err < 0)
{
puts("WSAStartup failed !");
exit(EXIT_FAILURE);
}
#endif
}
void end(void)
{
#ifdef WIN32
WSACleanup();
#endif
}
void app(SocketCallback cb)
{
SOCKET sock = init_connection();
char buffer[BUF_SIZE];
/* the index for the array */
int actual = 0;
int max = sock;
/* an array for all clients */
Client clients[MAX_CLIENTS];
fd_set rdfs;
while(1)
{
int i = 0;
FD_ZERO(&rdfs);
/* add STDIN_FILENO */
FD_SET(STDIN_FILENO, &rdfs);
/* add the connection socket */
FD_SET(sock, &rdfs);
/* add socket of each client */
for(i = 0; i < actual; i++)
{
FD_SET(clients[i].sock, &rdfs);
}
if(select(max + 1, &rdfs, NULL, NULL, NULL) == -1)
{
perror("select()");
exit(errno);
}
/* something from standard input : i.e keyboard */
if(FD_ISSET(STDIN_FILENO, &rdfs))
{
/* stop process when type on keyboard */
break;
}
else if(FD_ISSET(sock, &rdfs))
{
/* new client */
SOCKADDR_IN csin;
::memset(&csin, 0, sizeof(SOCKADDR_IN));
size_t sinsize = sizeof csin;
int csock = accept(sock, (SOCKADDR *)&csin, &sinsize);
if(csock == SOCKET_ERROR)
{
perror("accept()");
continue;
}
/* what is the new maximum fd ? */
max = csock > max ? csock : max;
FD_SET(csock, &rdfs);
Client c = { csock };
strncpy(c.name, buffer, BUF_SIZE - 1);
std::cout << "Accepted new connection from client-" << actual << std::endl;
clients[actual] = c;
actual++;
cb(clients[i].sock, 0, 0, 0);
}
else
{
int i = 0;
for(i = 0; i < actual; i++)
{
//- a client is talking
if(FD_ISSET(clients[i].sock, &rdfs))
{
Client client = clients[i];
size_t num_bytes_from_client = read_client(clients[i].sock, buffer);
std::cout << "received " << num_bytes_from_client << " bytes from client-" << i << std::endl;
//- client disconnected
if (num_bytes_from_client == 0)
{
cb(clients[i].sock, 1, 0, 0);
closesocket(clients[i].sock);
remove_client(clients, i, &actual);
continue;
}
cb(clients[i].sock, 2, num_bytes_from_client, buffer);
break;
}
}
}
}
clear_clients(clients, actual);
end_connection(sock);
}
void clear_clients(Client *clients, int actual)
{
int i = 0;
for(i = 0; i < actual; i++)
{
closesocket(clients[i].sock);
}
}
void remove_client(Client *clients, int to_remove, int *actual)
{
/* we remove the client in the array */
memmove(clients + to_remove, clients + to_remove + 1, (*actual - to_remove - 1) * sizeof(Client));
/* number client - 1 */
(*actual)--;
}
void send_message_to_all_clients(Client *clients, Client sender, int actual, const char *buffer, char from_server)
{
int i = 0;
char message[BUF_SIZE];
message[0] = 0;
for(i = 0; i < actual; i++)
{
/* we don't send message to the sender */
if(sender.sock != clients[i].sock)
{
if(from_server == 0)
{
strncpy(message, sender.name, BUF_SIZE - 1);
strncat(message, " : ", sizeof message - strlen(message) - 1);
}
strncat(message, buffer, sizeof message - strlen(message) - 1);
write_client(clients[i].sock, message);
}
}
}
int init_connection(void)
{
SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
SOCKADDR_IN sin;
::memset(&sin, 0, sizeof(SOCKADDR_IN));
if(sock == INVALID_SOCKET)
{
perror("socket()");
exit(errno);
}
sin.sin_addr.s_addr = htonl(INADDR_ANY);
sin.sin_port = htons(PORT);
sin.sin_family = AF_INET;
if(bind(sock,(SOCKADDR *) &sin, sizeof sin) == SOCKET_ERROR)
{
perror("bind()");
exit(errno);
}
std::cout << "Waiting for new connections on port " << PORT << std::endl;
if(listen(sock, MAX_CLIENTS) == SOCKET_ERROR)
{
perror("listen()");
exit(errno);
}
return sock;
}
void end_connection(int sock)
{
closesocket(sock);
}
int read_client(SOCKET sock, char *buffer)
{
int n = 0;
if((n = recv(sock, buffer, BUF_SIZE, 0)) < 0)
{
perror("recv()");
/* if recv error we disonnect the client */
n = 0;
}
return n;
}
void write_client(SOCKET sock, const char *buffer)
{
if(send(sock, buffer, strlen(buffer), 0) < 0)
{
perror("send()");
exit(errno);
}
}
#ifndef SERVER_H
#define SERVER_H
#ifdef WIN32
#include <winsock2.h>
#elif defined (linux)
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h> /* close */
#include <netdb.h> /* gethostbyname */
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define closesocket(s) close(s)
typedef int SOCKET;
typedef struct sockaddr_in SOCKADDR_IN;
typedef struct sockaddr SOCKADDR;
typedef struct in_addr IN_ADDR;
#else
#error not defined for this platform
#endif
#define CRLF "\r\n"
#define PORT 5001
#define MAX_CLIENTS 1
#define BUF_SIZE 128
#include "client.h"
typedef void(*SocketCallback)(SOCKET s, int e, size_t n, char * b);
void init(void);
void end(void);
void app(SocketCallback cb);
int init_connection(void);
void end_connection(int sock);
int read_client(SOCKET sock, char *buffer);
void write_client(SOCKET sock, const char *buffer);
void send_message_to_all_clients(Client *clients, Client client, int actual, const char *buffer, char from_server);
void remove_client(Client *clients, int to_remove, int *actual);
void clear_clients(Client *clients, int actual);
#endif /* guard */
<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>fr.soleil</groupId>
<artifactId>super-pom-C-CPP-device</artifactId>
<version>RELEASE</version>
</parent>
<groupId>fr.soleil.device</groupId>
<artifactId>yat-client-socket-test-${aol}-${mode}</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>nar</packaging>
<name>ClientSocketTester</name>
<description>a yat::ClientSocket test</description>
<build>
<plugins>
<plugin>
<groupId>org.freehep</groupId>
<artifactId>freehep-nar-plugin</artifactId>
<configuration>
<cpp>
<includePaths>
<includePath>${project.basedir}/src</includePath>
</includePaths>
<options>
<option>-Wno-uninitialized</option>
<option>-Wno-unused-parameter</option>
<option>-Wno-unused-variable</option>
</options>
</cpp>
</configuration>
</plugin>
</plugins>
</build>
<scm>
<connection>${scm.connection.svn.tango-cs}:share/yat</connection>
<developerConnection>${scm.developerConnection.svn.tango-cs}:share/yat</developerConnection>
<url>${scm.url.svn.tango-cs}/share/yat</url>
</scm>
<dependencies>
<dependency>
<groupId>fr.soleil.lib</groupId>
<artifactId>YAT-${aol}-${library}-${mode}</artifactId>
<version>1.7.2</version>
</dependency>
</dependencies>
<developers>
<developer>
<id>leclercq</id>
<name>leclercq</name>
<url>http://controle/</url>
<organization>Synchrotron Soleil</organization>
<organizationUrl>http://www.synchrotron-soleil.fr</organizationUrl>
<roles>
<role>manager</role>
</roles>
<timezone>1</timezone>
</developer>
</developers>
</project>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment