C - TCP Server/Client Example
So I can run the server code with:
./server
But how can I run the client code?
I tried with:
./client name file.txt
"42416 segmentation fault (core dumped)"
Where “name” is the hostname given by “gethostbyname” as seen in this example:
C Program to display hostname and IP address - GeeksforGeeks
and “file.txt” is a file in the same folder.
Here's a description of the client code:
"Now let us look at the client code. To understand how it works, it is necessary to understand how it is invoked. Assuming it is called client, a typical call is:
client flits.cs.vu.nl usr/tom/filename >f
This call only works if the server is already running on flits.cs.vu.nl and the file usr/tom/filename exists and the server has read access to it.
The client code starts with some includes and declarations. Execution begins by checking to see if it has been called with the right number of arguments(argc = 3 means the program plus two arguments) Note that argv[1] contains the server’s name (e.g, flits.cs.vu.nl) and is converted to an IP adress by gethostbyname. "
client.c
Code:
/* This page contains the client program. The following one contains the
* server program. Once the server has been compiled and started, clients
* anywhere on the Internet can send commands (file names) to the server.
* The server responds by opening and returning the entire file requested.
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#define SERVER_PORT 12345 /* arbitrary, but client and server must agree */
#define BUF_SIZE 4096 /* block transfer size */
int main(int argc, char **argv)
{
int c, s, bytes;
char buf[BUF_SIZE]; /* buffer for incoming file */
char obuf[BUF_SIZE]; /* buffer for outgoing file */
struct hostent *h; /* info about server */
struct sockaddr_in channel; /* holds IP address */
if (argc != 3) fatal("Usage: client server-name file-name");
h = gethostbyname(argv[1]); /* look up host's IP address */
if (!h) fatal("gethostbyname failed");
s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s < 0) fatal("socket");
memset(&channel, 0, sizeof(channel));
channel.sin_family= AF_INET;
memcpy(&channel.sin_addr.s_addr, h->h_addr, h->h_length);
channel.sin_port= htons(SERVER_PORT);
c = connect(s, (struct sockaddr *) &channel, sizeof(channel));
if (c < 0) fatal("connect failed");
/* Connection is now established. Send file name including 0 byte at end. */
write(s, argv[2], strlen(argv[2])+1);
/* Go get the file and write it to a local file
(new or existing, overwritten) of the same name. */
FILE *dst;
sprintf(obuf, "out/%s", argv[2]);
dst = fopen(obuf, "w+");
while (1) {
bytes = read(s, buf, BUF_SIZE); /* read from socket */
if (bytes <= 0) exit(0); /* check for end of file */
fwrite(buf, sizeof(char), bytes, dst);
// write(1, buf, bytes); /* write to standard output */
}
fclose(dst);
}
fatal(char *string)
{
printf("%s\n", string);
exit(1);
}
server.c
ast_networks_5e_tcp_client.c * GitHub