I'm having issues with my connect() method on the client side of my socket programming. I'm not sure if the issue is with my code or my method of running it. I'm running it in two seperate terminal windows - one for the server (which I'm running first) with the command './server 8080' and one for the client with the command './client 4 8080 hello'. When I run my code, the server program stops in the while loop just after the printf("this prints\n") line. I presume this means that it is waiting for a client to connect to it. The client program fails on the connect() call, and prints out my error message "Connection Failed". My code is posted below.
Server Code:
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <sys/wait.h>
#define bufsize 1024
void eatZombies(int n){
wait3(NULL,WNOHANG,NULL); // Nom Nom
}
int main(int argc, char *argv[]){
int sock, length, msgsock, status;
struct sockaddr_in server;
pid_t id;
signal(SIGCHLD, &eatZombies);
int server_fd = socket(AF_INET, SOCK_STREAM, 0);
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(atoi(argv[1])); // this time 1st arg is port#
if(bind(server_fd, (struct sockaddr *)&server, sizeof(server)) < 0){
printf("Error binding the socket\n");
exit(0);
}
if(listen(server_fd, SOMAXCONN) < 0){
printf("Error listening for connections\n");
exit(0);
}
char buffer[1024] = {0};
char *hello = "Hello from server";
int addrlen = sizeof(server);
while(1){
printf("this prints\n");
int client_fd = accept(server_fd, (struct sockaddr *)&server, (socklen_t*)&addrlen);
printf("this doesnt\n");
if(client_fd < 0){
printf("Error accepting connection\n");
exit(0);
}
// the next call makes a new child process that will actually handle the client.
id = fork();
// when id == 0, this is the child and needs to do the work for the server.
// when if > 0, this is the parent, and it should just loop around,
// when id < 0, we had an error.
if(id > 0){
continue;
}
else if(id < 0){
printf("Error\n");
exit(0);
}
read(client_fd, buffer, 1024);
printf("%s\n", buffer);
write(client_fd, hello, strlen(hello), 0);
printf("Hello message sent\n");
exit(0);
}
return 0;
}
Client Code:
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define bufsize 1024
int main(argc, argv) int argc; char *argv[];{
int sock, rval;
struct hostent *host;
struct sockaddr_in server; // not a pointer
char buf[bufsize];
printf("%d\n", argc);
if(argc != 4){
printf("usage:\ntcpclient hostname port string\n\n");
return(-1);
}
// look up hostname (server) using DNS
if ((host = gethostbyname(argv[1])) == 0) {
fprintf(stderr, "%s: unknown host\n", argv[1]);
return(-1);
}
// Set up fields for socket to point to host and port
bcopy(host->h_addr, &server.sin_addr, host->h_length);
server.sin_family = AF_INET;
server.sin_port = htons(atoi(argv[2]));
// Create socket
sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock < 0){
printf("Socket Creation Failed\n");
exit(0);
}
// connect (3-way handshake)
if(connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0){
printf("Connection Failed\n");
exit(0);
}
// Copy the arg into buf so we can send it to the server
strncpy(buf, argv[3], bufsize);
// Send sentence to server
send(sock, buf, strlen(buf), 0);
printf("Message sent\n");
// read response from server
rval = read(sock, buf, bufsize);
// print result to window
fprintf(stdout,"%s\n", buf);
close(sock);
}
When running ./client 4 8080 hello, 4 is the host name. You meant to call ./client localhost 8080 hello.
So it was just a mistake in calling the application, not in the code.
Related
I'm learning c++ and coming from a Network Engineer background, and it is fun for me to program something that I'm familiar with it on the network side. I started creating a BGP speaker.
Here is my environment:
[mybgp]<------------TCP-Port-179------------->[bird]
Here is my current code.
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#define BIND_ADDR INADDR_ANY
#define BIND_PORT htons(179)
int createServerSocket(){
//Create Socket
int serverSocket = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP);
if (serverSocket < 0) {
fprintf(stderr, "socket(): %s\n", strerror(errno));
return 1;
}
return serverSocket;
}
int createBind(const int &serverSocket, sockaddr_in &serverAddr){
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = BIND_PORT;
serverAddr.sin_addr.s_addr = INADDR_ANY;
int bind_ret = bind(serverSocket, (sockaddr *) &serverAddr, sizeof(serverAddr));
// if (bind(serverSocket, (struct sockaddr*) &serverAddr, sizeof(serverAddr)) == -1) {
// std::cerr << "Can't bind to ip/port";
// return -2;
// }
if (bind_ret < 0) {
fprintf(stderr, "bind(): %s\n", strerror(errno));
close(serverSocket);
return 1;
}
return bind_ret;
}
int createListener(const int &serverSocket){
int amount;
int listen_ret = listen(serverSocket, 3);
if (listen_ret < 0) {
fprintf(stderr, "listen(): %s\n", strerror(errno));
close(serverSocket);
return 1;
}
return listen_ret;
}
int acceptConnect(const int &serverSocket, sockaddr_in &clientAddr){
fprintf(stderr, "waiting for any client...\n");
char ip_str[INET_ADDRSTRLEN];
socklen_t caddr_len = sizeof(clientAddr);
int serverConn = accept(serverSocket, (sockaddr *) &clientAddr, &caddr_len);
if (serverConn < 0) {
fprintf(stderr, "accept(): %s\n", strerror(errno));
close(serverSocket);
close(serverConn);
return 1;
}
inet_ntop(AF_INET, &(clientAddr.sin_addr), ip_str, INET_ADDRSTRLEN);
fprintf(stderr, "accept(): new client from %s.\n", ip_str);
return serverConn;
}
int main(){
//Create Socket
int serverSocket = createServerSocket();
// declare server and client address struct
// bind socket.
sockaddr_in serverAddr, clientAddr;
memset(&serverAddr, 0, sizeof(serverAddr));
int bind_ret = createBind(serverSocket, serverAddr);
// listening for connection
int listen_ret = createListener(serverSocket);
int serverConn = acceptConnect(serverSocket, clientAddr);
// we only do one at a time, no new client.
char buffer[4048] = {0};
char valread;
valread = read( serverConn , buffer, 4048);
printf("%s\n",buffer );
close(serverSocket);
return 0;
}
My current state is that I'm able to:
Create Socket
Bind the Socket to IP
Listening
Accept a Single Connection(Single thread for now)
Received Data
At step 5, I received a gibberish TCP Message from the BGP speaker(BIRD). Knowing how the BGP Protocol works, this TCP message is in an OPEN Message Format. To establish BGP peering, mybgp and bird need to go back and for with different types of messages and agree.
For me to be able to accomplish this peering, I have to:
Decode[Received Package]
Encode[send package]
How can I decode/encode the TCP packet so I can start the process of BGP peering.
I programmed client and server codes. Both client and server have two interfaces and two separate IP addresses. To check the result, i made two tap loopbacks.
And then, i check the server and client. It seems that client is sending packets over both sockets but server only receives packets from one socket.
Could you please guide me what is the problem with my code or maybe the loopbaks?
client
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <iostream>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/socket.h>
#define BUFLEN 2048
#define MSGS 5 /* number of messages to send */
int main(void)
{
struct sockaddr_in myaddr, remaddr;
int fd, i, slen=sizeof(remaddr);
char buf[BUFLEN]; /* message buffer */
int recvlen; /* # bytes in acknowledgement message */
char *server = "192.168.10.10"; /* change this to use a different server */
//////////////////////////////////
struct sockaddr_in myaddr2, remaddr2;
int fd2, slen2=sizeof(remaddr2);
char buf2[BUFLEN]; /* message buffer */
int recvlen2; /* # bytes in acknowledgement message */
char *server2 = "192.168.11.11"; /* change this to use a different server */
//////////////////////////////
/* create a socket */
if ((fd=socket(AF_INET, SOCK_DGRAM, 0))==-1)
printf("socket created\n");
/////////////////////////////
if ((fd2=socket(AF_INET, SOCK_DGRAM, 0))==-1)
printf("socket2 created\n");
/////////////////////////////
/* bind fd and fd2 */
memset((char *)&myaddr, 0, sizeof(myaddr));
myaddr.sin_family = AF_INET;
//myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
inet_pton(AF_INET, "192.168.10.10", &myaddr.sin_addr.s_addr);
myaddr.sin_port = htons(2000);
/////////////////////////////
memset((char *)&myaddr2, 0, sizeof(myaddr2));
myaddr2.sin_family = AF_INET;
//myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
inet_pton(AF_INET, "192.168.11.11", &myaddr2.sin_addr.s_addr);
myaddr2.sin_port = htons(2001);
/////////////////////////////
if (bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) {
perror("bind failed");
return 0;
}
/////////////////////////////
if (bind(fd2, (struct sockaddr *)&myaddr2, sizeof(myaddr2)) < 0) {
perror("bind2 failed");
return 0;
}
/////////////////////////////
// printf("binding ip %s to port %d\n", myaddr.sin_addr.s_addr, myaddr.sin_port);
/* now define remaddr, the address to whom we want to send messages */
/* For convenience, the host address is expressed as a numeric IP address */
/* that we will convert to a binary format via inet_aton */
memset((char *) &remaddr, 0, sizeof(remaddr));
remaddr.sin_family = AF_INET;
remaddr.sin_port = htons(3000);
if (inet_aton(server, &remaddr.sin_addr)==0) {
fprintf(stderr, "inet_aton() failed\n");
exit(1);
}
/////////////////////////////
memset((char *) &remaddr2, 0, sizeof(remaddr2));
remaddr2.sin_family = AF_INET;
remaddr2.sin_port = htons(4000);
if (inet_aton(server2, &remaddr2.sin_addr)==0) {
fprintf(stderr, "inet_aton2() failed\n");
exit(1);
}
/////////////////////////////
/* now let's send the messages */
for (i=0; i < MSGS; i++) {
printf("Sending packet %d to %s port %d\n", i, server, remaddr.sin_port);
sprintf(buf, "This is packet %d", i);
if (sendto(fd, buf, strlen(buf), 0, (struct sockaddr *)&remaddr, slen)==-1) {
perror("sendto");
exit(1);
}
printf("socket %i SENT A PACKET \n", fd);
printf("Sending packet %d to %s port %d\n", i, server2, remaddr2.sin_port);
sprintf(buf2, "This is packet %d", i);
if (sendto(fd2, buf2, strlen(buf2), 0, (struct sockaddr *)&remaddr2, slen2)==-1) {
perror("sendto2");
exit(1);
}
printf("socket %i SENT A PACKET \n", fd2);
}
close(fd);
close(fd2);
return 0;
}
server
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <errno.h>
#include <iostream>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <netdb.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define BUFSIZE 2048
int
main(int argc, char **argv)
{
int n;
fd_set readfds;
struct timeval tv;
struct sockaddr_in myaddr; /* our address */
struct sockaddr_in remaddr; /* remote address */
socklen_t addrlen = sizeof(remaddr); /* length of addresses */
int recvlen; /* # bytes received */
int fd; /* our socket */
unsigned char buf[BUFSIZE]; /* receive buffer */
/////////////////////
struct sockaddr_in myaddr2; /* our address */
struct sockaddr_in remaddr2; /* remote address */
socklen_t addrlen2 = sizeof(remaddr2); /* length of addresses */
int recvlen2; /* # bytes received */
int fd2; /* our socket */
unsigned char buf2[BUFSIZE]; /* receive buffer */
/////////////////////
/* create a UDP socket */
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("cannot create socket\n");
return 0;
}
printf("socket %i is open \n", fd);
///////////////////////////////
if ((fd2 = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("cannot create socket2\n");
return 0;
}
printf("socket %i is open \n", fd2);
///////////////////////////////
// clear the set ahead of time
FD_ZERO(&readfds);
// add our descriptors to the set
FD_SET(fd, &readfds);
FD_SET(fd2, &readfds);
// since we got s2 second, it's the "greater", so we use that for
// the n param in select()
n = fd2 + 1;
/* bind the socket to any valid IP address and a specific port */
memset((char *)&myaddr, 0, sizeof(myaddr));
myaddr.sin_family = AF_INET;
//myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
inet_pton(AF_INET, "192.168.10.10", &myaddr.sin_addr.s_addr);
myaddr.sin_port = htons(3000);
if (bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) {
perror("bind failed");
return 0;
}
///////////////////////////
memset((char *)&myaddr2, 0, sizeof(myaddr2));
myaddr2.sin_family = AF_INET;
//myaddr2.sin_addr.s_addr = htonl(INADDR_ANY);
inet_pton(AF_INET, "192.168.11.11", &myaddr2.sin_addr.s_addr);
myaddr2.sin_port = htons(4000);
if (bind(fd2, (struct sockaddr *)&myaddr2, sizeof(myaddr2)) < 0) {
perror("bind2 failed");
return 0;
}
// wait until either socket has data ready to be recv()d (timeout 10.5 secs)
tv.tv_sec = 50;
tv.tv_usec = 500000;
for (;;) {
int rv = select(n, &readfds, NULL, NULL, &tv);
if (rv == -1) {
perror("select"); // error occurred in select()
} else if (rv == 0) {
printf("Timeout occurred! No data after 10.5 seconds.\n");
} else {
// one or both of the descriptors have data
if (FD_ISSET(fd, &readfds)) {
printf("socket %i RECEIVED A PACKET \n", fd);
printf("waiting on port %d\n", myaddr.sin_port);
recvlen = recvfrom(fd, buf, BUFSIZE, 0, (struct sockaddr *)&remaddr, &addrlen);
if (recvlen > 0) {
buf[recvlen] = 0;
printf("received message: \"%s\" (%d bytes)\n", buf, recvlen);
}
else
printf("uh oh - something went wrong!\n");
//sprintf(buf, "ack %d", msgcnt++);
}
if (FD_ISSET(fd2, &readfds)) {
printf("socket %i RECEIVED A PACKET \n", fd2);
printf("waiting on port %d\n", myaddr2.sin_port);
recvlen2 = recvfrom(fd2, buf2, BUFSIZE, 0, (struct sockaddr *)&remaddr2, &addrlen2);
if (recvlen2 > 0) {
buf[recvlen2] = 0;
printf("received message2: \"%s\" (%d bytes)\n", buf2, recvlen2);
}
else
printf("uh oh - something went wrong2!\n");
//sprintf(buf, "ack %d", msgcnt++);
}
}
}
}
result is shown in the picture:
================
Right now i checked the program in ns3 simulator network. It works correctly. so it seems that problem is with loopback. Please guide me how could i make loopback and test it over localhost.
I am trying to get a very basic hello world UDP sender and UDP multicast listener to work. I have a PC but have a virtual machine with the Linux OS CentOS. It has no problems connecting to the internet. The sender and listener are two separate programs, Eclipse is my environment.
The Sender...
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#define UDP_PORT 5403
#define UDP_GROUP "225.0.0.1" // 127.0.0.1
int main(int argc, char *argv[])
{
struct sockaddr_in addr;
int fd;
struct ip_mreq mreq;
char *message="Hello, World!";
int message_size = strlen(message) + 1;
// Create a UDP socket
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0)
{
perror("socket(...) ");
return -1;
}
// allow multiple sockets to use the same PORT number
u_int reuse_port = 1;
if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &reuse_port, sizeof(reuse_port)) < 0)
{
perror("setsockopt(...) ");
return -1;
}
// set up destination address
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(UDP_GROUP);
addr.sin_port = htons(UDP_PORT);
printf("Begin sendto(...) infinite loop\n");
while (true)
{
printf("Sending message: %s, of size: %d\n", message, message_size);
if (sendto(fd, message, message_size, 0, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
perror("sendto(...): ");
return -1;
}
// printf("message sent: %s\n", message);
sleep(1);
}
return 1;
}
The Listener...
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#define UDP_PORT 5403
#define UDP_GROUP "225.0.0.1"
#define MAX_BUFFER_SIZE 256
int main(int argc, char *argv[])
{
struct sockaddr_in addr;
int fd, nbytes;
socklen_t addrlen;
struct ip_mreq mreq;
char msgbuf[MAX_BUFFER_SIZE];
u_int reuse_port = 1;
// Create a socket
fd = socket(AF_INET,SOCK_DGRAM,0);
if (fd < 0)
{
perror("create socket failed");
return -1;
}
// allow multiple sockets to use the same PORT number
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse_port, sizeof(reuse_port)) < 0)
{
perror("Reusing port number failed");
return -1;
}
// set up destination address
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(UDP_PORT);
if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
perror("bind");
return -1;
}
// Set the recvfrom timeout after 1 s
struct timeval tv;
tv.tv_sec = 2;
tv.tv_usec = 0;
if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0)
{
perror("Error setting recvfrom timeout\n");
return -1;
}
// use setsockopt() to request that the kernel join a multicast group
mreq.imr_multiaddr.s_addr = inet_addr(UDP_GROUP);
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
{
perror("setsockopt");
return -1;
}
addrlen = sizeof(addr);
printf("Begin recvfrom(...) infinite loop\n");
while (true)
{
nbytes = recvfrom(fd, msgbuf, MAX_BUFFER_SIZE, 0, (struct sockaddr *)&addr, &addrlen);
if (nbytes < 0)
{
printf("recvfrom timeout\n");
}
else
{
printf("message received: %s\n", msgbuf);
}
}
return 1;
}
Every second, the sender program printf's "Sending message: Hello, World!, of size: 14" and every two seconds the receiver printf's "recvfrom timeout". I have set Wireshark to look at UDP traffic and I definitely see the sento data. The recvfrom is not getting any data. I have tried using many different Group IP's from 255.0.0.0 to 239.255.255.255, no change. I have tried many different ports, no change. Is their a special setup I need to do on my network card? I'm not sure what else to do. Small edit, the recvfrom and sendto message should not have "&".
Below is the basic client and server code .
While iam trying to start an appliaction(which has to keep running in the machine once we send a msg to server) during connect call.
using system(/bin/myApplication) in the client code (This basically is a simple c executable with an infinite loop,assuming my application has to be running);
Once iam starting the application the server is in CLOSED_WAIT State and its coming back to listen only if i stop this application .
The issue is with the server socket in CLOSED_WAIT state, Is there a way that this application keep running as a seperate process and server would be in listen state again.
Client Code: There is a system command after read.and it starts an application(basically is an c executable with an infinite while loop)
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
int sockfd = 0, n = 0;
char recvBuff[1024];
struct sockaddr_in serv_addr;
if(argc != 2)
{
printf("\n Usage: %s <ip of server> \n",argv[0]);
return 1;
}
memset(recvBuff, '0',sizeof(recvBuff));
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Error : Could not create socket \n");
return 1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(5000);
if(inet_pton(AF_INET, argv[1], &serv_addr.sin_addr)<=0)
{
printf("\n inet_pton error occured\n");
return 1;
}
if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\n Error : Connect Failed \n");
return 1;
}
while ( (n = read(sockfd, recvBuff, sizeof(recvBuff)-1)) > 0)
{
recvBuff[n] = 0;
if(fputs(recvBuff, stdout) == EOF)
{
printf("\n Error : Fputs error\n");
}
}
system(/bin/myApplication);
if(n < 0)
{
printf("\n Read error \n");
}
return 0;
Server Code:
int main(int argc, char *argv[])
{
int listenfd = 0, connfd = 0;
struct sockaddr_in serv_addr;
char sendBuff[1025];
time_t ticks;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_addr, '0', sizeof(serv_addr));
memset(sendBuff, '0', sizeof(sendBuff));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(5000);
bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
listen(listenfd, 10);
while(1)
{
connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
ticks = time(NULL);
snprintf(sendBuff, sizeof(sendBuff), "%.24s\r\n", ctime(&ticks));
write(connfd, sendBuff, strlen(sendBuff));
close(connfd);
sleep(1);
}
}
My Sample C File , which iam trying to execute using system command in client
code. with
gcc Sample.c -o myApplication
int main(int argc, char *argv[])
{
while(1)
{
}
}
I have tried using fork , but still the socket is in same state , is there anyway that this application runs seperately and doesnt effect the socket nor does it depend on the parent process(Server here).
Your client app never closes the socket, and since the sample app you spawn loops forever, the client never exits. This leaves the TCP connection state hanging on both sides.
In the client, try closing the socket before spawning the sample app.
Also, I think you're confused about the TCP states. A server endpont in the LISTEN state does not transition to CLOSE_WAIT and back. The LISTEN endpoint (the socket you called listen() on) will stay in that state until closed. The connected endpoint (the socket returned by accept()) will transition through various states during its lifetime.
If you're using the netstat command to see the states, be sure to use the -a flag to display the listening endpoints as well.
I added the below line before the system command
fcntl(sockfd, F_SETFD, fcntl(sockfd, F_GETFD) | FD_CLOEXEC);
And Changed my client code to
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
int sockfd = 0, n = 0;
char recvBuff[1024];
struct sockaddr_in serv_addr;
if(argc != 2)
{
printf("\n Usage: %s <ip of server> \n",argv[0]);
return 1;
}
memset(recvBuff, '0',sizeof(recvBuff));
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Error : Could not create socket \n");
return 1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(5000);
if(inet_pton(AF_INET, argv[1], &serv_addr.sin_addr)<=0)
{
printf("\n inet_pton error occured\n");
return 1;
}
if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\n Error : Connect Failed \n");
return 1;
}
while ( (n = read(sockfd, recvBuff, sizeof(recvBuff)-1)) > 0)
{
recvBuff[n] = 0;
if(fputs(recvBuff, stdout) == EOF)
printf("\n Error : Fputs error\n");
}
}
fcntl(sockfd, F_SETFD, fcntl(sockfd, F_GETFD) | FD_CLOEXEC);
system("/software/itcsm/itcsm/refasset/bin/start_script.sh 1");
if(n < 0)
{
printf("\n Read error \n");
}
printf("\n after system \n");
return 0;
}
By default whenever we fork a process (which system command does), the child inherits all the parent's file descriptors. If the child doesn't need those descriptors, it SHOULD close them voluntarily on file descriptor using fcntl(sockfd, F_SETFD, fcntl(sockfd, F_GETFD) | FD_CLOEXEC);
I have a client - server model using 2 C++ files. The client and server communicate through a socket. The user enters strings to the client's stdin and then the client passes that to the server. However, I want to simulate the user using a python program. This is my attemp:
from subprocess import Popen, PIPE, STDOUT
host_name = raw_input("Enter host name: ")
port = raw_input("Enter port: ")
p = Popen(["./client", host_name, port], stdout=PIPE, stdin=PIPE, stderr=STDOUT)
p.stdin.write("DEVICE:3:MALFUNCTIONING")
This doesn't work. It starts the client process and the arguments, but does not write the string DEVICE:3:MALFUNCTIONING to it. Any suggestion?
This is briefly my client code:
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
printf("Please enter the message: ");
memset(buffer, 0, 256);
fgets(buffer,255,stdin);
n = write(sockfd,buffer,strlen(buffer));
if (n < 0)
error("ERROR writing to socket");
memset(buffer, 0, 256);
n = read(sockfd,buffer,255);
if (n < 0)
error("ERROR reading from socket");
printf("%s\n",buffer);
close(sockfd);
I am not sure how you create your client and server, but here's my implementation which is pretty much the same as yours for the python program simulating the user.
Github gist: https://gist.github.com/yanhan/5791613
I have a few suspicions of what may be going wrong based on your code snippets for the client:
server_addr variable not set properly
bug in the server code
Like mata said, it'll be more helpful if you could show any output from stdout/stderr and stacktraces.
EDIT: Just wanted to add that the following links might help:
http://en.wikibooks.org/wiki/C_Programming/Networking_in_UNIX
http://rabbit.eng.miami.edu/info/functions/internet.html#clientsample
http://rabbit.eng.miami.edu/info/functions/internet.html#serversample
I am pasting my code here for convenience.
sim.py:
from subprocess import Popen, PIPE
def run():
# this should work if you change to
# host_name = raw_input
# port = raw_input
host_name = '127.0.0.1'
port = '8124'
p = Popen(['./client', host_name, port], stdin=PIPE, close_fds=True)
myInput = raw_input()
p.stdin.write(myInput)
p.communicate()
if __name__ == '__main__':
run()
client.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define BUFSZ 256
int main(int argc, char *argv[])
{
int sockfd, ret, exitCode = 0;
char buffer[BUFSZ];
memset(buffer, 0, BUFSZ);
fgets(buffer, sizeof(buffer), stdin);
char *hostname = argv[1];
int port = atoi(argv[2]);
// echo out the stuff just to see
printf("hostname = %s\n", hostname);
printf("port = %d\n", port);
printf("msg = %s\n", buffer);
// creates the socket
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
fprintf(stderr, "client: socket() failed\n");
exit(1);
}
struct sockaddr_in sockAddr;
memset(&sockAddr, 0, sizeof(struct sockaddr_in));
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons(port);
sockAddr.sin_addr.s_addr = inet_addr(hostname);
// connect to server
ret = connect(sockfd, (const struct sockaddr *)&sockAddr, sizeof(struct sockaddr));
if (ret == -1) {
fprintf(stderr, "client: connect failed\n");
exitCode = 1;
goto done;
}
// send buffer
ssize_t charsSent = send(sockfd, buffer, strlen(buffer)+1, 0);
printf("client: chars sent: %d\n", (int)charsSent);
/*
// this seems to work as well
write(sockfd, buffer, strlen(buffer)+1);
*/
done:
close(sockfd);
return exitCode;
}
server.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define PORTNUM 8124
#define BUFSZ 256
int main(int argc, char *argv[])
{
char buf[BUFSZ];
int ret, exitCode = 1;
// create socket
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
int recvFd;
if (sockfd == -1) {
fprintf(stderr, "server: Error creating socket\n");
exit(1);
}
struct sockaddr_in sockAddr;
memset(&sockAddr, 0, sizeof(struct sockaddr_in));
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons(PORTNUM);
sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
// bind socket
ret = bind(sockfd, (const struct sockaddr *)&sockAddr, sizeof(struct sockaddr));
if (ret == -1) {
fprintf(stderr, "server: bind failed\n");
exitCode = 1;
goto done;
}
// listen for connection. max of 1 connection
ret = listen(sockfd, 1);
if (ret == -1) {
fprintf(stderr, "server: listen failed\n");
exitCode = 1;
goto done;
}
struct sockaddr_in dest;
socklen_t sockLen;
ssize_t bytesReceived;
while (1) {
// accept connection from client
recvFd = accept(sockfd, (struct sockaddr *)&dest, &sockLen);
if (recvFd == -1) {
fprintf(stderr, "server: accept failed\n");
exitCode = 1;
break;
}
// receive message from client
bytesReceived = recv(recvFd, buf, BUFSZ, 0);
if (bytesReceived == -1) {
fprintf(stderr, "server: recv failed\n");
exitCode = 1;
break;
} else {
printf("server: received %s", buf);
fflush(stdout);
}
}
done:
close(sockfd);
return exitCode;
}