This web page is a good starting point for anyone who wants to learn how to program with the UNIX socket API :
http://www.cs.dartmouth.edu/~campbell/cs60/socketprogramming.html
Many of the IP connected applications I have written need to support both Windows and Unix/Linux. There are some minor differences between the two socket APIs but these are primarily related to configuration.
Once the code has been configured the vast majority of the code will be the same for both operating systems.
These programs use the following predefined macros to select between Windows and Unix/Linux :
#if (_WIN32) || (_WIN64)
Here are versions of the code included in the above URL, that compile on both Windows and Linux.
echoServer.c
#if (_WIN32) || (_WIN64)
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment (lib, "Ws2_32.lib")
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MAXLINE 4096 /*max text line length*/
#define SERV_PORT 3000 /*port*/
#define LISTENQ 8 /*maximum number of client connections */
int main (int argc, char **argv)
{
int n;
socklen_t clilen;
char buf[MAXLINE];
#if (_WIN32) || (_WIN64)
SOCKET listenfd, connfd;
WSADATA wsaData;
int iResult;
#else
int listenfd, connfd;
#endif
struct sockaddr_in cliaddr, servaddr;
#if (_WIN32) || (_WIN64)
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
#endif
//creation of the socket
listenfd = socket (AF_INET, SOCK_STREAM, 0);
//preparation of the socket address
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
bind (listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
listen (listenfd, LISTENQ);
printf("%s\n","Server running...waiting for connections.");
for ( ; ; ) {
clilen = sizeof(cliaddr);
connfd = accept (listenfd, (struct sockaddr *) &cliaddr, &clilen);
printf("%s\n","Received request...");
while ( (n = recv(connfd, buf, MAXLINE,0)) > 0) {
printf("%s","String received from and resent to the client:");
puts(buf);
send(connfd, buf, n, 0);
}
if (n < 0) {
perror("Read error");
exit(1);
}
close(connfd);
}
//close listening socket
close (listenfd);
#if (_WIN32) || (_WIN64)
WSACleanup();
#endif
}
echoClient.c
#if (_WIN32) || (_WIN64)
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment (lib, "Ws2_32.lib")
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MAXLINE 4096 /*max text line length*/
#define SERV_PORT 3000 /*port*/
int
main(int argc, char **argv)
{
struct sockaddr_in servaddr;
char sendline[MAXLINE], recvline[MAXLINE];
#if (_WIN32) || (_WIN64)
SOCKET sockfd;
WSADATA wsaData;
int iResult;
#else
int sockfd;
#endif
#if (_WIN32) || (_WIN64)
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
#endif
//basic check of the arguments
//additional checks can be inserted
if (argc !=2) {
perror("Usage: TCPClient <IP address of the server>");
exit(1);
}
//Create a socket for the client
//If sockfd<0 there was an error in the creation of the socket
if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) <0) {
perror("Problem in creating the socket");
exit(2);
}
//Creation of the socket
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr= inet_addr(argv[1]);
servaddr.sin_port = htons(SERV_PORT); //convert to big-endian order
//Connection of the client to the socket
if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr))<0) {
perror("Problem in connecting to the server");
exit(3);
}
while (fgets(sendline, MAXLINE, stdin) != NULL) {
send(sockfd, sendline, strlen(sendline), 0);
if (recv(sockfd, recvline, MAXLINE,0) == 0){
//error: server terminated prematurely
perror("The server terminated prematurely");
exit(4);
}
printf("%s", "String received from the server: ");
fputs(recvline, stdout);
}
#if (_WIN32) || (_WIN64)
WSACleanup();
#endif
exit(0);
}
If you have found this solution useful then please do hit the Google (+1) button so that others may be able to find it as well.
Copyright © 2015 Delta Numerix