Code:
Here is the server code:
#define WIN // WIN for Winsock and BSD for BSD sockets
//----- Include files ---------------------------------------------------------
#include <stdio.h> // Needed for printf()
#include <string.h> // Needed for memcpy() and strcpy()
#include <winsock.h> // Needed for all Winsock stuff
//----- Defines ---------------------------------------------------------------
#define PORT_NUM 1050 // Arbitrary port number for the server
//===== Main program ==========================================================
int main(void)
{
WORD wVersionRequested = MAKEWORD(1,1); // Stuff for WSA functions
WSADATA wsaData; // Stuff for WSA functions
unsigned int welcome_s; // Welcome socket descriptor
struct sockaddr_in server_addr; // Server Internet address
unsigned int connect_s; // Connection socket descriptor
struct sockaddr_in client_addr; // Client Internet address
struct in_addr client_ip_addr; // Client IP address
int addr_len; // Internet address length
char buf[100]; // Output buffer for data
// This stuff initializes winsock
WSAStartup(wVersionRequested, &wsaData);
// >>> Step #1 <<<
// Create a welcome socket
// - AF_INET is Address Family Internet and SOCK_STREAM is streams
welcome_s = socket(AF_INET, SOCK_STREAM, 0);
// >>> Step #2 <<<
// Fill-in server (my) address information and bind the welcome socket
// - See winsock.h for a description of struct sockaddr_in
server_addr.sin_family = AF_INET; // Address family to use
server_addr.sin_port = htons(PORT_NUM); // Port number to use
server_addr.sin_addr.s_addr = htonl(INADDR_ANY); // Listen on any IP address
bind(welcome_s, (struct sockaddr *)&server_addr, sizeof(server_addr));
// >>> Step #3 <<<
// Listen on welcome socket for a connection
listen(welcome_s, 1);
//----------------------SELECT-------------------------------
unsigned int fdmax; // maximum file descriptor number
fd_set master; // master file descriptor list
fd_set read_fds; // temp file descriptor list for select()
FD_ZERO(&master); // clear the master and temp sets
FD_ZERO(&read_fds);
FD_SET(welcome_s, &master);
fdmax = welcome_s;
printf("FDMAX: %i", fdmax);
unsigned int i, j, nbytes;
// main loop
for(;;) {
read_fds = master; // copy it
if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) {
perror("select");
exit(4);
}
// run through the existing connections looking for data to read
for(i = 0; i <= fdmax; i++) {
if (FD_ISSET(i, &read_fds)) { // we got one!!
if (i == welcome_s) {
// handle new connections
addr_len = sizeof client_addr;
connect_s = accept(welcome_s,
(struct sockaddr *)&client_addr,
&addr_len);
if (connect_s == 0) {
perror("accept");
} else {
FD_SET(connect_s, &master); // add to master set
if (connect_s > fdmax) { // keep track of the max
fdmax = connect_s +1;
}
// Print an informational message that accept completed
if (send(connect_s, "Welcome!", sizeof("Welcome!"), 0) == -1) {
perror("send");
}
printf("Accept completed (IP address of client = %s port = %d) \n",
inet_ntoa(client_ip_addr), ntohs(client_addr.sin_port));
}
} else {
// handle data from a client
if ((nbytes = recv(i, buf, sizeof buf, 0)) <= 0) {
// got error or connection closed by client
if (nbytes == 0) {
// connection closed
printf("selectserver: socket %d hung up\n", i);
} else {
perror("recv");
}
closesocket(i); // bye!
FD_CLR(i, &master); // remove from master set
} else {
printf("BYTES: %i\n", nbytes);
// we got some data from a client
for(j = 0; j <= fdmax; j++) {
// send to everyone!
if (FD_ISSET(j, &master)) {
// except the welcome_s and ourselves
if (j != welcome_s && j != i) {
if (send(j, buf, nbytes, 0) == -1) {
perror("send");
}
}
}
}
printf("We got some data: %s, fdmax: %i!\n", buf, fdmax);
}
} // END handle data from client
} // END got new incoming connection
} // END looping through file descriptors
} // END for(;;)--and you thought it would never end!
//----------------------END SELECT-------------------------------
// >>> Step #7 <<<
// Close the welcome and connect sockets
// Clean-up winsock
WSACleanup();
}
And here is the client code:
//----- Include files ---------------------------------------------------------
#include <stdio.h> // Needed for printf()
#include <string.h> // Needed for memcpy() and strcpy()
#include <winsock.h> // Needed for all Winsock stuff
//----- Defines ---------------------------------------------------------------
#define PORT_NUM 1050 // Port number used at the server
#define IP_ADDR "127.0.0.1" // IP address of server (*** HARDWIRED ***)
//===== Main program ==========================================================
void main(int argc, char *argv[]){
WORD wVersionRequested = MAKEWORD(1,1); // Stuff for WSA functions
WSADATA wsaData; // Stuff for WSA functions
unsigned int client_s; // Client socket descriptor
struct sockaddr_in server_addr; // Server Internet address
char out_buf[100]; // Output buffer for data
char in_buf[100]; // Input buffer for data
// This stuff initializes winsock
WSAStartup(wVersionRequested, &wsaData);
// >>> Step #1 <<<
// Create a client socket
// - AF_INET is Address Family Internet and SOCK_STREAM is streams
client_s = socket(AF_INET, SOCK_STREAM, 0);
server_addr.sin_addr.s_addr = inet_addr(IP_ADDR); // IP address to use
// >>> Step #2 <<<
// Fill-in the server's address information and do a connect with the
// listening server usingh the client socket. The connect() will block.
server_addr.sin_family = AF_INET; // Address family to use
server_addr.sin_port = htons(PORT_NUM); // Port num to use
// server_addr.sin_addr.s_addr = inet_addr(IP_ADDR); // IP address to use
connect(client_s, (struct sockaddr *)&server_addr, sizeof(server_addr));
// >>> Step #3 <<<
// Receive from the server using the client socket
recv(client_s, in_buf, sizeof(in_buf), 0);
printf("Received from server... data = '%s' \n", in_buf);
// >>> Step #4 <<<
// Send to the server using the client socket
strcpy(out_buf, "Test message from client to server");
send(client_s, out_buf, (strlen(out_buf) + 1), 0);
char c;
char mess[100];
int q = 0;
while (1) {
while ((c = getchar()) != '\n') {
mess[q++] = c;
}
mess[q] = '\0';
q = 0;
if (strcmp(mess, "stop") == 0)
break;
strcpy(out_buf, mess);
send(client_s, out_buf, (strlen(out_buf) + 1), 0);
}
// >>> Step #5 <<<
// Close the client socket
closesocket(client_s);
// Clean-up winsock
WSACleanup();
}
I have discovered a little more.