Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago .I would like to know the simplest and most effective way to open and write data to a socket in the C programming language for network programming.
374k 114 114 gold badges 1.3k 1.3k silver badges 1k 1k bronze badges asked Nov 21, 2008 at 3:02 44.4k 49 49 gold badges 126 126 silver badges 162 162 bronze badgesYou're right, using sockets in C has a difficult syntax. Later languages like Java and Python make it a snap by comparison. The best tutorial I've found for doing socket programming in C is Beej's Guide to Network Programming. I recommend you start at the beginning to get a good overview, but if you just need to get some code working now, you can skip ahead to the section titled Client-Server Background.
1,267 1 1 gold badge 17 17 silver badges 33 33 bronze badges answered Nov 21, 2008 at 3:09 Bill the Lizard Bill the Lizard 404k 210 210 gold badges 572 572 silver badges 888 888 bronze badgesThis is silly. Sockets are defined as a C API, and "later languages" have to make all those C calls at some level. There are "later libraries" in C that will also do it easily, right up to making, say, an HTTP request instead of mucking around with sockets. You can easily have a client function that will take an IP address in host or dot notation as a char * string, a port number as an int , and return you a FILE * stream denoting the connected circuit, or a null pointer with errno set to something useful.
Commented Dec 18, 2013 at 23:54POSIX 7 minimal runnable client server TCP example
Get two computers in a LAN, e.g. your home WiFi network.
Run the server on one computer with:
./server.out
Get the IP of the server computer with ifconfig , e.g. 192.168.0.10 .
On the other computer, run:
./client.out 192.168.0.10
Now type lines on the client, and the server will return them incremented by 1 (ROT-1 cypher).
server.c
#define _XOPEN_SOURCE 700 #include #include #include #include #include #include /* getprotobyname */ #include #include #include int main(int argc, char **argv) < char buffer[BUFSIZ]; char protoname[] = "tcp"; struct protoent *protoent; int enable = 1; int i; int newline_found = 0; int server_sockfd, client_sockfd; socklen_t client_len; ssize_t nbytes_read; struct sockaddr_in client_address, server_address; unsigned short server_port = 12345u; if (argc >1) < server_port = strtol(argv[1], NULL, 10); >protoent = getprotobyname(protoname); if (protoent == NULL) < perror("getprotobyname"); exit(EXIT_FAILURE); >server_sockfd = socket( AF_INET, SOCK_STREAM, protoent->p_proto /* 0 */ ); if (server_sockfd == -1) < perror("socket"); exit(EXIT_FAILURE); >if (setsockopt(server_sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable)) < 0) < perror("setsockopt(SO_REUSEADDR) failed"); exit(EXIT_FAILURE); >server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = htonl(INADDR_ANY); server_address.sin_port = htons(server_port); if (bind( server_sockfd, (struct sockaddr*)&server_address, sizeof(server_address) ) == -1 ) < perror("bind"); exit(EXIT_FAILURE); >if (listen(server_sockfd, 5) == -1) < perror("listen"); exit(EXIT_FAILURE); >fprintf(stderr, "listening on port %d\n", server_port); while (1) < client_len = sizeof(client_address); client_sockfd = accept( server_sockfd, (struct sockaddr*)&client_address, &client_len ); while ((nbytes_read = read(client_sockfd, buffer, BUFSIZ)) >0) < printf("received:\n"); write(STDOUT_FILENO, buffer, nbytes_read); if (buffer[nbytes_read - 1] == '\n') newline_found; for (i = 0; i < nbytes_read - 1; i++) buffer[i]++; write(client_sockfd, buffer, nbytes_read); if (newline_found) break; >close(client_sockfd); > return EXIT_SUCCESS; >
client.c
#define _XOPEN_SOURCE 700 #include #include #include #include #include #include #include /* getprotobyname */ #include #include #include int main(int argc, char **argv) < char buffer[BUFSIZ]; char protoname[] = "tcp"; struct protoent *protoent; char *server_hostname = "127.0.0.1"; char *user_input = NULL; in_addr_t in_addr; in_addr_t server_addr; int sockfd; size_t getline_buffer = 0; ssize_t nbytes_read, i, user_input_len; struct hostent *hostent; /* This is the struct used by INet addresses. */ struct sockaddr_in sockaddr_in; unsigned short server_port = 12345; if (argc >1) < server_hostname = argv[1]; if (argc >2) < server_port = strtol(argv[2], NULL, 10); >> /* Get socket. */ protoent = getprotobyname(protoname); if (protoent == NULL) < perror("getprotobyname"); exit(EXIT_FAILURE); >sockfd = socket(AF_INET, SOCK_STREAM, protoent->p_proto); if (sockfd == -1) < perror("socket"); exit(EXIT_FAILURE); >/* Prepare sockaddr_in. */ hostent = gethostbyname(server_hostname); if (hostent == NULL) < fprintf(stderr, "error: gethostbyname(\"%s\")\n", server_hostname); exit(EXIT_FAILURE); >in_addr = inet_addr(inet_ntoa(*(struct in_addr*)*(hostent->h_addr_list))); if (in_addr == (in_addr_t)-1) < fprintf(stderr, "error: inet_addr(\"%s\")\n", *(hostent->h_addr_list)); exit(EXIT_FAILURE); > sockaddr_in.sin_addr.s_addr = in_addr; sockaddr_in.sin_family = AF_INET; sockaddr_in.sin_port = htons(server_port); /* Do the actual connection. */ if (connect(sockfd, (struct sockaddr*)&sockaddr_in, sizeof(sockaddr_in)) == -1) < perror("connect"); return EXIT_FAILURE; >while (1) < fprintf(stderr, "enter string (empty to quit):\n"); user_input_len = getline(&user_input, &getline_buffer, stdin); if (user_input_len == -1) < perror("getline"); exit(EXIT_FAILURE); >if (user_input_len == 1) < close(sockfd); break; >if (write(sockfd, user_input, user_input_len) == -1) < perror("write"); exit(EXIT_FAILURE); >while ((nbytes_read = read(sockfd, buffer, BUFSIZ)) > 0) < write(STDOUT_FILENO, buffer, nbytes_read); if (buffer[nbytes_read - 1] == '\n') < fflush(stdout); break; >> > free(user_input); exit(EXIT_SUCCESS); >
Message length
The read calls on both client and server run inside while loops.
Like when reading from files, the OS may split up messages arbitrarily to make things faster, e.g. one packet may arrive much earlier than the other.
So the protocol must specify a convention of where messages stop. Common methods include:
Next steps
This example is limited because:
Solving those problems requires threading and possibly other calls like poll .