Skip to content

Instantly share code, notes, and snippets.

@jepio
Last active August 29, 2015 14:04
Show Gist options
  • Save jepio/5d742fb45919d68ffbab to your computer and use it in GitHub Desktop.
Save jepio/5d742fb45919d68ffbab to your computer and use it in GitHub Desktop.
A C socket server and a Python socket client.
#!/usr/bin/env python2
""" USAGE: client.py <ip> <port> """
from __future__ import print_function
from socket import socket, error, AF_INET, SOCK_STREAM
import sys
def client():
## Create an internet domain stream socket
sock = socket(AF_INET, SOCK_STREAM)
## Connect to the address and port provided at launch
try:
sock.connect((sys.argv[1], int(sys.argv[2])))
except error as err:
print(err)
sys.exit(1)
## Read the user message
try:
message = raw_input()
while message:
message += '\n' # Add a new line so that printing is nicer
messlen = sock.send(message) # Send a message to server
if messlen != len(message):
print ("Failed to send message")
print ("Received:", end=' ')
data = sock.recv(255) # Receive server response (max 255 chars)
sys.stdout.write(data)
message = raw_input() # Read next input
except EOFError as err:
pass
finally:
sock.close() # Close socket
if __name__ == "__main__":
if len(sys.argv) != 3:
print(__doc__)
sys.exit(0)
else:
client()
CFLAGS += -Wall -Wextra -g -std=gnu99
all: server
clean:
rm -f server
/*
Adapted from the howto on the website
www.linuxhowtos.org/C_C++/socket.htm
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <netinet/in.h>
#include <string.h>
#include <signal.h>
void error(char* msg)
{
perror(msg);
exit(1);
}
/** Zombie process handler **/
void zombie_handler(int _signal)
{
signal(SIGCHLD, zombie_handler);
int status;
int pid = wait(&status);
printf("PID = %d , status = %d\n", pid, status);
}
/** Respond to incoming socket message **/
void interact(int sockfd)
{
int n;
char buffer[256] = { 0 };
while ((n = read(sockfd, buffer, 255)) != 0) { /* Read chars from socket */
if (n < 0)
error("ERROR reading from socket");
printf("Here is the message: %s", buffer);
char* msg = "copy gold leader\n";
int m = write(sockfd, msg, strlen(msg)); /* Write message to socket */
if (m < 0)
error("ERROR writing to socket");
bzero(buffer, 256);
}
}
int main(int argc, char* argv[])
{
signal(SIGCHLD, zombie_handler);
/*
* The alternative is to simply ignore:
* signal(SIGCHLD, SIG_IGN);
*/
if (argc < 2) {
error("ERROR, require port number");
}
int portno = atoi(argv[1]); /* Port number */
/* Create an internet domain stream socket */
int sockfd = socket(AF_INET, SOCK_STREAM, 0); /* Socket file descriptior */
if (sockfd < 0)
error("ERROR opening socket");
/* Initialize server socket port number, address, and family */
struct sockaddr_in serv_addr = { .sin_family = AF_INET,
.sin_port = htons(portno),
.sin_addr = { INADDR_ANY } };
/* Bind socket to address */
if (bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
error("ERROR on binding");
/* Listen on socket (max 5 pending connections) */
listen(sockfd, 5);
struct sockaddr_in cli_addr; /* Internet address structures */
unsigned int clilen = sizeof(cli_addr);
while (true) {
/*
* Block until a connection is made, fill incoming entity parameters
* into cli_addr, and return a file descriptor to be used for
* responses.
*/
int newsockfd = accept(sockfd, (struct sockaddr*)&cli_addr, &clilen);
if (newsockfd < 0)
error("ERROR on accept");
/* Creates a child process to do the talking */
int pid = fork();
if (pid < 0) { /* A process was not forked */
error("ERROR on fork");
} else if (pid == 0) { /* We are in the child process */
close(sockfd); /* Need to close the server process - check why */
interact(newsockfd);
exit(0);
} else {
close(newsockfd); /* Mother process */
}
}
close(sockfd);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment