Linux Network Programming 7 & mdash; use TCP to chat with both parties.

Source: Internet
Author: User

Linux Network Programming 7 -- use TCP to implement mutual chat and linux Network Programming
Ideas

The main thread is responsible for sending messages, and the other thread is responsible for receiving messages. This is true for both the server and client.

Note:

After Party A closes the socket port used for communication, the port will not be closed immediately. Because the information of Party B may not be sent. Therefore, at this time, the recv of Party A is still in the blocking state, and the information will be waited for again. In this case, after Party B sends A message to Party A and Party A returns the recv, the socket port of A is closed, and the recv of Party A returns-1.

At this time, because the socket port of A has been closed, the recv of B has to return 0.

Note: If the code is as follows: After Party A closes the socket port, Party A does not have A blocked recv in the program, then the socket port is closed.

Code

The server and client programs of this Code are written together. For more information, see annotations.

/*************************************** * *********************************> File Name: my_chat.c> Author: KrisChou> Mail: zhoujx0219@163.com> Created Time: thu 28 Aug 2014 11:06:04 pm cst ********************************* ***************************************/ # include <stdio. h> # include <stdlib. h> # include <string. h> # include <sys/types. h> # include <sys/socket. h> # include <netinet/in. h> # include <arp A/inet. h> # include <unistd. h> # include <pthread. h> # include <netdb. h> # define ACTIVE 1 # define PASSIVE 0 # define SERVER_PORT 1314 # define CLIENT_PORT 1350/* implement */void * chat_handler (void * arg) for receiving messages through a thread) {int fd_client = (int) arg; char buf [1024]; int test; while (memset (buf, 0, 1024), (test = recv (fd_client, buf, 1024, 0)> 0) {write (1, buf, strlen (buf);} // used to test the recv returned value printf ("break child while! \ N "); printf (" test = % d \ n ", test); return (void *) 0; // close (fd_client);} int main (int argc, char * argv []) // exe peer_ip {int flag; int fd_peer;/* socket descriptor of the other party, returned by acccept */if (argc = 1) {flag = PASSIVE;} else if (argc = 2) {flag = ACTIVE;}/* ----------------------------------------- socket -------------------------------------- */int sfd; /* sfd is the local socket descriptor */sfd = socket (AF_INET, SOCK_STREAM, 0); if (sfd =-1) {perror ("socket"); exit (1 );} /* ------------ ------------------------- bind host */char my_hostname [1024] = ""; struct hostent * p; gethostname (my_hostname, 1024);/* get the local hostname, so that ip address */p = gethostbyname (my_hostname) can be identified based on hostname;/* obtain the pointer to the struct hostent struct */struct sockaddr_in local_addr Based on hostname; /* bind the socket port and IP struct */memset (& loca Rochelle ADDR, 0, sizeof (local_addr); local_addr.sin_family = AF_INET; if (flag = ACTIVE) {local_addr.sin_port = htons (CLIENT_PORT);/* as the ACTIVE party, the port to be bound is client_port */} else {local_addr.sin_port = htons (SERVER_PORT);/* as the server, the port server_port * to be bound is both the local port */} local_addr.sin_addr = * (struct in_addr *) (p-> h_addr_list) [0]; /* bind IP Address * // * local IP Address */if (-1 = bind (sfd, (struct sockaddr *) & local_addr, sizeo F (local_addr) {perror ("bind"); close (sfd); exit (1) ;}/ * -------------------------------- if it is a server, listen + accept ------------------------------------------ */if (flag = PASSIVE) {if (-1 = listen (sfd, 10) {perror ("listen"); close (sfd ); exit (1);} struct sockaddr_in peer_addr;/* structure for storing the contact information of the returned socket descriptor, which is the outgoing parameter */int len; memset (& peer_addr, 0, sizeof (peer_addr); len = sizeof (peer_addr );// Accept returns the socket descriptor of the other party, and both peer_addr and len are outgoing parameters fd_peer = accept (sfd, (struct sockaddr *) & peer_addr, & len); printf ("% s: % d begin to talk! \ N ", inet_ntoa (release), ntohs (peer_addr.sin_port); close (sfd); // kris} else if (flag = ACTIVE)/* ------------- if it is ACTIVE, connect ----------------------------------------------- */{fd_peer = sfd; // if it is an active party, the local party actually communicates with sfd. /* The active party wants to connect to the other party. You need to know the IP address of the other party and pass it through the command line parameters. You also need to know the server port number. The program has been written to death */struct sockaddr_in server_addr; memset, 0, sizeof (server_addr); server_addr.sin_family = AF_INET; server_addr.sin_port = htons (SERVER_PORT);/* adds htons. If it is 12345678 on the right, it is uploaded to the left or 12345678; if htons is not added, if the right side is 12345678, it will be 78563412 to the left. */server_addr.sin_addr.s_addr = inet_addr (argv [1]);/* If the connection fails,-1 will be returned, after sleeping for one second, continue to connect */while (connect (sfd, (struct Sockaddr *) & server_addr, sizeof (server_addr) =-1) {sleep (1); printf ("connecting .... \ n ");} printf (" success! \ N ") ;}pthread_t thd; pthread_create (& thd, NULL, chat_handler, (void *) fd_peer); char msg [1024]; while (memset (msg, 0, 1024), fgets (msg, 1024, stdin )! = NULL) {send (fd_peer, msg, strlen (msg), 0);} close (fd_peer); // used to test printf ("close \ n "); pthread_join (thd, NULL);}/* Communication in this code is on the socket port fd_peer */
Program exit Result Discussion

1. if A presses ctrl + D (the main thread exits the while LOOP, closes the port, and blocks it on pthread_join), B then sends A message, A recv in the thread, and prints it, in this case, the socket port of A is actually closed, and the recv returns-1. The loop is exited, the thread is exited, and A is finished. B. Because the socket port of A is closed, the recv in the thread returns 0. The loop is exited and the thread is exited. At this time, if B presses ctrl + D, it also exits the program.

2. After one party presses ctrl + D, the other party immediately presses ctrl + D. The two sides are deadlocked. If one party presses ctrl + c and forcibly exits the program, the other party will also leave. Cause: the socket port is actually closed due to a strong retreat of one party, And the recv in the sub-thread of the other side returns 0, exits the loop, and exits the thread.

3. Press ctrl + c to exit. Then the sub-thread of the other party will be removed, for the same reason. Press ctrl + D on the other side to exit the program.

Summary

The recv return values are divided into the following three cases:

1. greater than 0. The size of the received data.

2. equal to 0. The socket port of the other party is actually closed.

3. Smaller than 0. Error. One of the situations is that, after the local socket port is actually closed, it tries to obtain data from the port.

The recv return value is actually similar to read.

Found

Send an empty message as follows:

send(fd_peer,"",0,0);

The recv of the other party does not return 0, and it is still blocked.

This is different from UDP. In UDP, one party sendto an empty message to the other party, and the other party's recvfrom returns 0.


Network chat room through linux Network Programming

This is quite challenging, but it is a pity that few people are willing to do it!
 
How to write the tcp protocol in linux network programming?

C/C ++ Basics
Linux basics: laruence's linux Private food
Computer Network
Advanced Programming in UNIX environment
I hope it will be helpful to you.


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.