Skip to content

Commit

Permalink
Do not use non-blocking sockets in the client (until we have an async…
Browse files Browse the repository at this point in the history
… API)
  • Loading branch information
Julius Pfrommer committed Apr 21, 2015
1 parent a70e393 commit 776266e
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 10 deletions.
21 changes: 15 additions & 6 deletions examples/networklayer_tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ static UA_StatusCode socket_write(UA_Connection *connection, const UA_ByteString
do {
#ifdef _WIN32
n = send((SOCKET)connection->sockfd, (const char*)buf->data, buf->length, 0);
if(n != 0 &&WSAGetLastError() != WSAEINTR)
if(n < 0 && WSAGetLastError() != WSAEINTR)
return UA_STATUSCODE_BADCONNECTIONCLOSED;
#else
n = send(connection->sockfd, (const char*)buf->data, buf->length, MSG_NOSIGNAL);
Expand All @@ -62,19 +62,28 @@ static UA_StatusCode socket_write(UA_Connection *connection, const UA_ByteString

static UA_StatusCode socket_recv(UA_Connection *connection, UA_ByteString *response, UA_UInt32 timeout) {
UA_StatusCode retval = UA_STATUSCODE_GOOD;
if(response->data == UA_NULL)
if(response->data == UA_NULL)
retval = connection->getBuffer(connection, response, connection->localConf.recvBufferSize);
if(retval != UA_STATUSCODE_GOOD)
return retval;
struct timeval tmptv = {0, timeout * 1000};
setsockopt(connection->sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tmptv, sizeof(struct timeval));
int ret = recv(connection->sockfd, (char*)response->data, response->length, 0);
if(ret <= -1) {
if(errno == EAGAIN) {
if(ret == 0) {
connection->releaseBuffer(connection, response);
connection->close(connection);
return UA_STATUSCODE_BADCONNECTIONCLOSED;
} else if(ret < 0) {
#ifdef _WIN32
if(WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEWOULDBLOCK) {
#else
if (errno == EAGAIN) {
#endif
return UA_STATUSCODE_BADCOMMUNICATIONERROR;
}
connection->releaseBuffer(connection, response);
return UA_STATUSCODE_BADINTERNALERROR;
connection->close(connection);
return UA_STATUSCODE_BADCONNECTIONCLOSED;
}
response->length = ret;
*response = UA_Connection_completeMessages(connection, *response);
Expand Down Expand Up @@ -518,7 +527,7 @@ UA_Connection ClientNetworkLayerTCP_connect(char *endpointUrl, UA_Logger *logger
return connection;
}
connection.state = UA_CONNECTION_OPENING;
socket_set_nonblocking(connection.sockfd);
//socket_set_nonblocking(connection.sockfd);
connection.write = socket_write;
connection.recv = socket_recv;
connection.close = socket_close;
Expand Down
10 changes: 9 additions & 1 deletion include/ua_connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,15 @@ struct UA_Connection {
UA_StatusCode (*getBuffer)(UA_Connection *connection, UA_ByteString *buf, size_t minSize); ///> Attach the data array to the buffer. Fails if minSize is larger than remoteConf allows
void (*releaseBuffer)(UA_Connection *connection, UA_ByteString *buf); ///> Release the buffer
UA_StatusCode (*write)(UA_Connection *connection, const UA_ByteString *buf); ///> The bytestrings cannot be reused after sending!
UA_StatusCode (*recv)(UA_Connection *connection, UA_ByteString *response, UA_UInt32 timeout); // timeout in milliseconds
/**
* Receive a message from the remote connection
* @param connection The connection
* @param response The response string. It is allocated by the connection and needs to be freed with connection->releaseBuffer
* @param timeout Timeout of the recv operation in milliseconds
* @return Returns UA_STATUSCODE_BADCOMMUNICATIONERROR if the recv operation can be repeated, UA_STATUSCODE_GOOD if it succeeded and
* UA_STATUSCODE_BADCONNECTIONCLOSED if the connection was closed.
*/
UA_StatusCode (*recv)(UA_Connection *connection, UA_ByteString *response, UA_UInt32 timeout);
void (*close)(UA_Connection *connection);
};

Expand Down
6 changes: 3 additions & 3 deletions src/client/ua_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ static UA_StatusCode HelAckHandshake(UA_Client *c) {
UA_ByteString_init(&reply);
do {
retval = c->connection.recv(&c->connection, &reply, c->config.timeout);
if(retval == UA_STATUSCODE_BADINTERNALERROR)
if(retval == UA_STATUSCODE_BADCONNECTIONCLOSED)
return retval;
} while(retval != UA_STATUSCODE_GOOD);

Expand Down Expand Up @@ -190,7 +190,7 @@ static UA_StatusCode SecureChannelHandshake(UA_Client *client) {
UA_ByteString_init(&reply);
do {
retval = client->connection.recv(&client->connection, &reply, client->config.timeout);
if(retval == UA_STATUSCODE_BADINTERNALERROR)
if(retval == UA_STATUSCODE_BADCONNECTIONCLOSED)
return retval;
} while(retval != UA_STATUSCODE_GOOD);

Expand Down Expand Up @@ -291,7 +291,7 @@ static void sendReceiveRequest(UA_RequestHeader *request, const UA_DataType *req
UA_ByteString_init(&reply);
do {
retval = client->connection.recv(&client->connection, &reply, client->config.timeout);
if(retval == UA_STATUSCODE_BADINTERNALERROR) {
if(retval == UA_STATUSCODE_BADCONNECTIONCLOSED) {
respHeader->serviceResult = retval;
return;
}
Expand Down

0 comments on commit 776266e

Please sign in to comment.