static t_stat net_detach(UNIT *uptr) { uint32 i; if (!(net_unit.flags & UNIT_ATT)) return SCPE_OK; /* if not attached simply return */ if (net_unit.flags & UNIT_SERVER) sim_close_sock(serviceDescriptor[1].masterSocket, TRUE); for (i = 0; i <= MAX_CONNECTIONS; i++) if (serviceDescriptor[i].ioSocket) sim_close_sock(serviceDescriptor[i].ioSocket, FALSE); free(net_unit.filename); /* free port string */ net_unit.filename = NULL; net_unit.flags &= ~UNIT_ATT; /* not attached */ return SCPE_OK; }
SOCKET sim_err_sock (SOCKET s, char *emsg, int32 flg) { int32 err = WSAGetLastError (); printf ("Sockets: %s error %d\n", emsg, err); sim_close_sock (s, flg); return INVALID_SOCKET; }
/* cannot use sim_check_conn to check whether read will return an error */ static t_stat net_svc(UNIT *uptr) { int32 i, j, k, r; SOCKET s; static char svcBuffer[BUFFER_LENGTH]; if (net_unit.flags & UNIT_ATT) { /* cannot remove due to following else */ sim_activate(&net_unit, net_unit.wait); /* continue poll */ if (net_unit.flags & UNIT_SERVER) { for (i = 1; i <= MAX_CONNECTIONS; i++) if (serviceDescriptor[i].ioSocket == 0) { s = sim_accept_conn(serviceDescriptor[1].masterSocket, NULL); if (s != INVALID_SOCKET) { serviceDescriptor[i].ioSocket = s; sim_debug(ACCEPT_MSG, &net_dev, "NET: " ADDRESS_FORMAT " Accepted connection %i with socket %i.\n", PCX, i, s); } } } else if (serviceDescriptor[0].ioSocket == 0) { serviceDescriptor[0].ioSocket = sim_connect_sock(net_unit.filename, "localhost", "3000"); if (serviceDescriptor[0].ioSocket == INVALID_SOCKET) return SCPE_IOERR; printf("\rWaiting for server ... Type g<return> (possibly twice) when ready" NLP); return SCPE_STOP; } for (i = 0; i <= MAX_CONNECTIONS; i++) if (serviceDescriptor[i].ioSocket) { if (serviceDescriptor[i].inputSize < BUFFER_LENGTH) { /* there is space left in inputBuffer */ r = sim_read_sock(serviceDescriptor[i].ioSocket, svcBuffer, BUFFER_LENGTH - serviceDescriptor[i].inputSize); if (r == -1) { sim_debug(DROP_MSG, &net_dev, "NET: " ADDRESS_FORMAT " Drop connection %i with socket %i.\n", PCX, i, serviceDescriptor[i].ioSocket); sim_close_sock(serviceDescriptor[i].ioSocket, FALSE); serviceDescriptor[i].ioSocket = 0; serviceDescriptor_reset(i); continue; } else { for (j = 0; j < r; j++) { serviceDescriptor[i].inputBuffer[serviceDescriptor[i].inputPosWrite++] = svcBuffer[j]; if (serviceDescriptor[i].inputPosWrite == BUFFER_LENGTH) serviceDescriptor[i].inputPosWrite = 0; } serviceDescriptor[i].inputSize += r; } } if (serviceDescriptor[i].outputSize > 0) { /* there is something to write in outputBuffer */ k = serviceDescriptor[i].outputPosRead; for (j = 0; j < serviceDescriptor[i].outputSize; j++) { svcBuffer[j] = serviceDescriptor[i].outputBuffer[k++]; if (k == BUFFER_LENGTH) k = 0; } r = sim_write_sock(serviceDescriptor[i].ioSocket, svcBuffer, serviceDescriptor[i].outputSize); if (r >= 0) { serviceDescriptor[i].outputSize -= r; serviceDescriptor[i].outputPosRead += r; if (serviceDescriptor[i].outputPosRead >= BUFFER_LENGTH) serviceDescriptor[i].outputPosRead -= BUFFER_LENGTH; } else printf("write %i" NLP, r); } } } return SCPE_OK; }