4 * @author Sebastian Hack
6 * A client for an lpp solving server.
8 * Copyright (C) 2005 Universitaet Karlsruhe
9 * Released under the GPL
18 #include <sys/socket.h>
19 #include <sys/types.h>
20 #include <sys/resource.h>
23 #include <netinet/in.h>
24 #include <arpa/inet.h>
31 #define INADDR_NONE (in_addr_t)(-1)
50 static int winsock_init(void) {
51 WORD wVersionRequested;
55 wVersionRequested = MAKEWORD( 2, 2 );
57 err = WSAStartup( wVersionRequested, &wsaData );
59 /* Tell the user that we could not find a usable */
64 /* Confirm that the WinSock DLL supports 2.2.*/
65 /* Note that if the DLL supports versions greater */
66 /* than 2.2 in addition to 2.2, it will still return */
67 /* 2.2 in wVersion since that is the version we */
70 if ( LOBYTE( wsaData.wVersion ) != 2 ||
71 HIBYTE( wsaData.wVersion ) != 2 ) {
72 /* Tell the user that we could not find a usable */
81 static int connect_tcp(const char *host, uint16_t port)
85 struct sockaddr_in sin;
92 memset(&sin, 0, sizeof(sin));
93 sin.sin_family = AF_INET;
94 sin.sin_port = htons(port);
96 if ((phe = gethostbyname(host)))
97 memcpy(&sin.sin_addr, phe->h_addr, phe->h_length);
98 else if((sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE) {
99 lpp_print_err("cannot get host entry for %s", host);
103 ppe = getprotobyname("tcp");
104 ERRNO_CHECK_RETURN(s = socket(PF_INET, SOCK_STREAM, ppe->p_proto), <, 0, -1);
105 ERRNO_CHECK_RETURN(connect(s, (struct sockaddr *) &sin, sizeof(sin)), <, 0, -1);
110 char **lpp_get_solvers(const char *host)
116 ERR_CHECK_RETURN(fd = connect_tcp(host, LPP_PORT), <, 0,
117 ("could not connect to %s", host), NULL);
119 comm = lpp_comm_new(fd, LPP_BUFSIZE);
121 lpp_writel(comm, LPP_CMD_SOLVERS);
124 res = malloc((n + 1) * sizeof(res[0]));
129 for(i = 0; i < n; ++i)
130 res[i] = lpp_reads(comm);
133 lpp_writel(comm, LPP_CMD_BYE);
140 void lpp_set_dbg(const char *host, int mask)
145 ERR_CHECK_RETURN_VOID(fd = connect_tcp(host, LPP_PORT), <, 0, ("could not connect to %s", host));
147 comm = lpp_comm_new(fd, LPP_BUFSIZE);
149 lpp_writel(comm, LPP_CMD_SET_DEBUG);
150 lpp_writel(comm, mask);
152 lpp_writel(comm, LPP_CMD_BYE);
158 void lpp_solve_net(lpp_t *lpp, const char *host, const char *solver)
163 ir_timer_t *t_send, *t_recv;
165 ERR_CHECK_RETURN_VOID(fd = connect_tcp(host, LPP_PORT), <, 0,
166 ("could not connect to %s", host));
168 comm = lpp_comm_new(fd, LPP_BUFSIZE);
171 lpp_writel(comm, LPP_CMD_SOLVER);
172 lpp_writes(comm, solver);
176 ERR_CHECK_RETURN_VOID(lpp_ack(fd, sizeof(buf), buf), == 0,
177 ("could not set solver: %s", solver));
180 t_send = ir_timer_new();
181 t_recv = ir_timer_new();
183 ir_timer_push(t_send);
184 lpp_writel(comm, LPP_CMD_PROBLEM);
185 lpp_serialize(comm, lpp, 1);
186 lpp_serialize_values(comm, lpp, lpp_value_start);
189 lpp->send_time = ir_timer_elapsed_usec(t_send);
193 int cmd = lpp_readl(comm);
195 case LPP_CMD_SOLUTION:
196 ir_timer_push(t_recv);
197 lpp_deserialize_stats(comm, lpp);
198 lpp_deserialize_values(comm, lpp, lpp_value_solution);
200 lpp->recv_time = ir_timer_elapsed_usec(t_recv);
204 lpp_readbuf(comm, buf, sizeof(buf));
205 buf[sizeof(buf) - 1] = '\0';
207 if(lpp->log != NULL) {
208 fputs(buf, lpp->log);
210 if(buf[n - 1] != '\n')
211 putc('\n', lpp->log);
216 fprintf(stderr, "solver process died unexpectedly\n");
219 fprintf(stderr, "invalid command: %s(%d)\n", lpp_get_cmd_name(cmd), cmd);
224 lpp_writel(comm, LPP_CMD_BYE);