Reputation: 147
I have the following code:
bytes_read = read(0, buffer_stdin, 65535);
printf("bytes read from stdin: %d\n", bytes_read);
bytes_written = write(sock, buffer_stdin, bytes_read);
printf("bytes written to socket: %d\n", bytes_written);
sock is the socket descriptor. In the code I have connected the socket to a server and the connection returned (0), indicating the connection was successful.
Now in the code above I type something into stdin, let's say "hello" and the number of bytes read would be 6 (because of null termination after letter 'o'). The program executes the first print statement.
But for some reason the program doesn't execute the second print statement. It just exits.
When I commented out line 3 where I write to the socket, the 2nd print statement executes.
My question is, why is the program exiting early without my instruction to do so?
Here is the preliminary code:
int main(int argc, char *argv[]) {
if (argc != 3) {
printf("Invalid arguments\n");
exit(1);
}
char *serverIP = argv[1]; /*Server hostname*/
char *portNumber = argv[2]; /*Port Number*/
void *numericAddress;
char buffer_stdin[65535];
char buffer_stdout[65535];
int bytes_read = 0;
int bytes_written = 0;
/*getting integral number of string representation of port number*/
in_port_t servPort = atoi(argv[2]);
/*------------------get binary number of hostname-----------------*/
struct addrinfo addrCriteria;
memset(&addrCriteria, 0, sizeof(addrCriteria));
addrCriteria.ai_family = AF_INET;
addrCriteria.ai_socktype = SOCK_STREAM;
addrCriteria.ai_protocol = IPPROTO_TCP;
struct addrinfo *addrList;
int rtnVal = getaddrinfo(serverIP, portNumber, &addrCriteria, &addrList);
if (rtnVal != 0) {
printf("getaddrinfo() failed\n");
exit(1);
}
if (rtnVal == 0) {
printf("getaddrinfo() successful\n");
}
numericAddress = &((struct sockaddr_in *) (addrList->ai_addr))->sin_addr;
((struct sockaddr_in *)(addrList->ai_addr))->sin_port = htons(servPort);
/*----------------------------------------------------------------*/
/*Creating socket*/
int sock = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP);
if (sock < 0) {
printf("error creating socket\n");
exit(1);
}
/*Establish connection to the echo server*/
int r = connect(sock, (struct sockaddr *) addrList, sizeof(addrList));
if (r < 0) {
printf("Connection failed\n");
exit(1);
}
if (r == 0) {
printf("connection succesful\n");
}
Upvotes: 2
Views: 2027
Reputation: 70382
The problem seems to be that the server closed the connection before your client had a chance to send data. Writing to a closed socket could result in a kind of error that is expressed as raising the SIGPIPE signal, unless that signal has been ignored. If the signal delivery of SIGPIPE has been suppressed (by setting its disposition to SIG_IGN), writing to a closed socket will cause an error result with errno
set to EPIPE.
Since your program does not ignore SIGPIPE or otherwise hand it, the default handler is used, which would likely cause the program to terminate. This explains your immediate problem.
You indicated in comments that you used port 80 for your "echo server". Unless you are running the program as root, 80 is within the privileged port range, so your program would not be able to listen on that port. In addition, port 80 is the well known port for the HTTP service. So, even if you started the "echo server" with root privileges, it would still likely fail because some other server (the web server) would already be listening on that port.
Assuming you directed your client at the web server, it is unknown what actually happened when your client attempted communication. For example, the web server may have delivered a RST packet as soon as the client connected. The connection completed successfully, but writing would fail.
To get the behavior you expect, you should choose an unprivileged port for your "echo server". Something relatively high and random, so that it will not conflict with other programs, and will not conflict with other users if you are on a shared machine.
Upvotes: 3