1 /**************************************************
2 * MULTIECHO CLIENT *
3 * *
4 * NO LICENSE, THIS CODE IS PUBLIC DOMAIN *
5 * *
6 * Written by Pioz *
7 * To compile: "gcc -o client client.c -lpthread" *
8 **************************************************/
9
10 #include <stdio.h> /* For printf() and fprintf() */
11 #include <sys/socket.h> /* For socket(), connect(), send() and recv() */
12 #include <arpa/inet.h> /* For sockaddr_in and inet_addr() */
13 #include <stdlib.h> /* For atoi() and exit() */
14 #include <string.h> /* For memset() */
15 #include <unistd.h> /* For close() */
16 #include <pthread.h> /* For pthread */
17
18 #define BUFSIZE 256
19
20 void dieWithError(char* errorMessage); /* Error handling function */
21 void* child(void* arg); /* Body of child process */
22
23 int sock; /* Socket descriptor, shared from two processes */
24
25 typedef struct data {
26 int field1;
27 char field2[BUFSIZE];
28 } data_t;
29
30 int main(int argc, char* argv[])
31 {
32 struct sockaddr_in servAddr; /* Server address */
33 unsigned short port; /* Server port */
34 char* servIP; /* Server IP address (dotted quad) */
35 char* word; /* String to send */
36 data_t data; /* The data in the network */
37 int dataSize; /* Bytes to send and receive */
38 int recvMsgSize; /* Receive bytes */
39 pthread_t pchild; /* Pointer to child process */
40
41 if ((argc < 3) || (argc > 4)) /* Test for correct number of arguments */
42 {
43 fprintf(stderr, "Usage: %s <Server IP> <Server port> <Word to send>\n", argv[0]);
44 exit(1);
45 }
46
47 servIP = argv[1]; /* First arg: server IP address (dotted quad) */
48 port = atoi(argv[2]); /* Second arg: server port */
49 word = argv[3]; /* Third arg: some info */
50 dataSize = sizeof(data_t); /* Size of data to receive */
51
52 /* Create a reliable, stream socket using TCP */
53 if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
54 dieWithError("socket() failed");
55
56 /* Construct the server address structure */
57 memset(&servAddr, 0, sizeof(servAddr)); /* Zero out structure */
58 servAddr.sin_family = AF_INET; /* Internet address family */
59 servAddr.sin_addr.s_addr = inet_addr(servIP); /* Server IP address */
60 servAddr.sin_port = htons(port); /* Server port */
61
62 /* Establish the connection to the echo server */
63 if (connect(sock, (struct sockaddr*)&servAddr, sizeof(servAddr)) < 0)
64 dieWithError("connect() failed");
65
66 if ( pthread_create(&pchild, 0, child, word) != 0 ) /* Create the child process */
67 dieWithError("pthread_create() failed");
68
69 for(;;) /* Run forever */
70 {
71 /* Receive up to the buffer size (minus 1 to leave space for a null terminator) bytes from the sender */
72 if ((recvMsgSize = recv(sock, &data, dataSize, 0)) <= 0)
73 dieWithError("recv() failed or connection closed prematurely");
74 data.field2[recvMsgSize - sizeof(int)] = '\0'; /* Terminate the string! */
75 printf("%d, %s\n", data.field1, data.field2); /* Print the data just received */
76 }
77
78 pthread_join(pchild, 0); /* Wait for the child to finish */
79 close(sock);
80 }
81
82 //////////////////////////////////////////////////////////////////////////////
83
84 void* child(void* arg)
85 {
86 data_t data;
87 strcpy(data.field2, (char*)arg);
88 int dataSize = sizeof(int) + strlen(data.field2); /* Real size of data to send */
89 int i;
90 for(i = 0; i < 10; i++) /* Send 10 msg */
91 {
92 data.field1 = i; /* This is a example! */
93 if (send(sock, &data, dataSize, 0) != dataSize)
94 dieWithError("send() sent a different number of bytes than expected");
95
96 sleep(2); /* 2 seconds of delay */
97 }
98 }
99
100 //////////////////////////////////////////////////////////////////////////////
101
102 void dieWithError(char* errorMessage)
103 {
104 perror(errorMessage);
105 exit(1);
106 }
Download | Top | Back | Home
Maintained by Pioz