linux下TCP/IP实现简单聊天程序

可以在同一台电脑上运行,在一个终端上运行服务器端,在一个终端上运行客户端。

服务器端的IP地址要和本地的IP相同,并分配端口号,客户端的默认设置为本地,端口号自动分配。

服务器端:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <arpa/inet.h>

#define MAXBUF 1024

int main(int argc, char *argv[])
{
    int pid;
    int sockfd, new_fd;
    socklen_t len;
    struct sockaddr_in my_addr, their_addr;
    unsigned int myport, lisnum;
    char buf[MAXBUF + 1];

    if (argv[2])
		myport = atoi(argv[2]);
    else
		myport = 7575;

    if (argv[3])
		lisnum = atoi(argv[3]);
	else
		lisnum = 5;

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
		perror("socket");
		exit(EXIT_FAILURE);
    }

    bzero(&my_addr, sizeof(my_addr));
    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(myport);
    if (argv[1])
		my_addr.sin_addr.s_addr = inet_addr(argv[1]);
    else
		my_addr.sin_addr.s_addr = INADDR_ANY;

    if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr))== -1)
    {
		perror("bind");
		exit(EXIT_FAILURE);
    }

    if (listen(sockfd,lisnum ) == -1)
    {
		perror("listen");
		exit(EXIT_FAILURE);
    }
    printf("wait for connect\n");
    len = sizeof(struct sockaddr);
    if ((new_fd =accept(sockfd, (struct sockaddr *) &their_addr,&len)) == -1)
    {
        perror("accept");
        exit(EXIT_FAILURE);
    }
    else
        printf("server: got connection from %s, port %d, socket %d\n",inet_ntoa(their_addr.sin_addr),ntohs(their_addr.sin_port), new_fd);

	if(-1==(pid=fork()))
	{
		perror("fork");exit(EXIT_FAILURE);
	}
	else if( pid == 0)
	{
		while (1)
		{
			bzero(buf, MAXBUF + 1);
			printf("input the message to send:");
			fgets(buf, MAXBUF, stdin);
			if (!strncasecmp(buf, "quit", 4))
			{
				printf("i will close the connect!\n");
				break;
			}
			len = send(new_fd, buf, strlen(buf) - 1, 0);
	  		if (len < 0)
			 {
				printf("message'%s' send failure!errno code is %d,errno message is '%s'\n",
				buf, errno, strerror(errno));
				break;
			}
		}
	}
	else
	{
		while(1)
		{
			bzero(buf, MAXBUF + 1);
			len = recv(new_fd, buf, MAXBUF, 0);
			if (len > 0)
				printf("message recv successful :'%s',%dByte recv\n",buf, len);
			else if (len < 0)
			{
				printf("recv failure!errno code is %d,errno message is '%s'\n",
				errno, strerror(errno));
				break;
			}
			else
			{
				printf("the other one close quit\n");
				break;
			}
		}
	}
	close(new_fd);
	close(sockfd);
    	return 0;
}

客户端:

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <resolv.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

#define MAXBUF 1024

int main(int argc, char **argv)
{
    int sockfd, len;
    struct sockaddr_in dest;
    char buffer[MAXBUF + 1];
    if (argc != 3)
    {
		printf(" error format,it must be:\n\t\t%s IP port\n",argv[0]);
		exit(EXIT_FAILURE);
    }

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		perror("Socket");
		exit(errno);
    }
    printf("socket created\n");

    bzero(&dest, sizeof(dest));
    dest.sin_family = AF_INET;
    dest.sin_port = htons(atoi(argv[2]));
    if (inet_aton(argv[1], (struct in_addr *) &dest.sin_addr.s_addr) == 0)
    {
		perror(argv[1]);	exit(errno);
    }
    if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest))==-1)
    {
		perror("Connect ");
		exit(errno);
    }
    printf("server connected\n");

	pid_t pid;
	if(-1==(pid=fork()))
	{
		perror("fork");exit(EXIT_FAILURE);
	}
	else if (pid==0)
	{
		while (1)
		{
			bzero(buffer, MAXBUF + 1);
			len = recv(sockfd, buffer, MAXBUF, 0);
			if (len > 0)
				printf("recv successful:'%s',%d byte recv\n",buffer, len);
			else if(len < 0)
			{
				perror("recv");
				break;
			}
			else
			{
				printf("the other one close ,quit\n");
				break;
			}
		}
	}
	else
	{
		while (1)
		{
			bzero(buffer, MAXBUF + 1);
			printf("pls send message to send:");
			fgets(buffer, MAXBUF, stdin);
			if (!strncasecmp(buffer, "quit", 4))
			{
				printf(" i will quit!\n");
				break;
			}
			len = send(sockfd, buffer, strlen(buffer) - 1, 0);
			if (len < 0)
			{
				perror("send");
				break;
			}
		}
	}
    close(sockfd);
    return 0;
}

服务器端执行 :           ./s 192.168.142.132 7575 5

客户端执行:               ./c 192.168.142.132 7575

其中,192.168.142.132是本机的IP地址.

服务器端信息:

[email protected]:/home/jieniyimiao/c_code/linux/ch13/sock_tcp_p_p_chat# ./s 192.168.142.132 7575 5

wait for connect

server: got connection from 192.168.142.132, port 44698, socket 4

input the message to send:jieniyimiap

input the message to send:ddddddddddddddddddddddddddd

input the message to send:dddddddddddddddddddddddddddd

input the message to send:aaaaaaaaaaaaaaaaaaaaaa

input the message to send:aaaaaaaaaaaaaaaaaaaaaaaa

input the message to send:message recv successful :‘dddddddddddddddddd‘,18Byte recv

message recv successful :‘ddddddddddddddddd‘,17Byte recv

message recv successful :‘ddddddddddddddddd‘,17Byte recv

message recv successful :‘dddddddddddddd‘,14Byte recv

message recv successful :‘ddddddddddddddd‘,15Byte recv

message recv successful :‘ddddddddddddddddd‘,17Byte recv

message recv successful :‘dddddddddddddd‘,14Byte recv

quit

i will close the connect!

客户端略:

用NETSTAT查看信息如下:

# netstat |grep 192.168.142.132

**********************************************************************************

tcp        0      0 192.168.142.132:7575    192.168.142.132:44698   ****

tcp        0      0 192.168.142.132:44698   192.168.142.132:7575    ****

时间: 2024-08-01 01:13:43

linux下TCP/IP实现简单聊天程序的相关文章

Linux下TCP/IP协议栈的简单脉络分析

最近在写网络编程方面的一些东西,然后遇到了关于传输上的小问题.由于之前有简单的看过一些TCP/IP详解的一些东西,所以索性就找了本<追踪LinuxTCP/IP代码运行>的书看了一上午,结果发现初次接触这些内核方面的东西,收获甚微.于是又在网上找相关类的大神博客,拿来拜读,虽然依然看的不是太明白,吸收的也不够好,但是我想以博客的形式把它记录下来,也希望能为我以后学这些东西开个好头吧 1.linux的网络协议栈的主要结构 (1)socket层 这层主要处理socket相关的东西,例如其各种结构的初

Linux下C语言多线程,网络通信简单聊天程序

原文:Linux下C语言多线程,网络通信简单聊天程序 功能描述:程序应用多线程技术,可是实现1对N进行网络通信聊天.但至今没想出合适的退出机制,除了用Ctr+C.出于演示目的,这里采用UNIX域协议(文件系统套接字),程序分为客户端和服务端.应用select函数来实现异步的读写操作. 先说一下服务端:首先先创建套接字,然后绑定,接下进入一个无限循环,用accept函数,接受“连接”请求,然后调用创建线程函数,创造新的线程,进入下一个循环.这样每当有一个新的“连接”被接受都会创建一个新的线程,实现

用qemu与gdb调试linux kernel tcp/ip协议栈

description 用gdb debug linux kernel容易吗?其实要走到这步真的不容易啊,其实也难道是不难,就是要知道的东西太多了.用gdb debug linux kernel 可以有2中方式:UML和qemu方式,这里主要说qemu,从源码编译安装qemu很费劲. 准备环境 linux OS: Debian7.5-i386(当时最新的Wheezy,装在VMware10上,我用的在线安装,安装后以text方式跑起来,我的笔记本配置资源有限!) root fs:Debian-Wh

Linux下静态IP地址的设置及TFTP服务的搭建

TFTP(Trivial File Transfer Protocol,简单文件传输协议)是TCP/IP协议族中的一个用来在客户机与服务器之间进行简单文件传输的协议,提供不复杂.开销不大的文件传输服务.TFTP承载在UDP上,提供不可靠的数据流传输服务,不提供存取授权与认证机制,使用超时重传方式来保证数据的到达. 一.在谈TFTP之前,先简单讲一下Linux网络配置,网络中最重要的当然是IP地址了,这里不讲IP协议,在后面的网络编程再讲解,这里主要学习一下Linux下配置IP,配置IP地址的方法

《Java项目实践》:简单聊天程序

<Java项目实践>:简单聊天程序 由于这个简单程序,还是涉及到很多的知识点,下面我们就一点一点的来完成. 我们熟悉的QQ聊天,就有一个界面,是吧,我们自己做一个简单的聊天程序,因此我们也就需要为Client写一个界面.因此,这就是我们第一步需要完成的任务. 第一步:为Client端写一个界面 完成一个界面有两种方法,一种是使用Frame对象来完成,另外一种是继承JFrame类来完成.本项目使用第二种. 第二种继承JFrame类完成的界面的程序如下: public class ChatClie

Linux下TCP网络编程与基于Windows下C#socket编程间通信

一.linux下TCP网络编程基础,需要了解相关函数 Socket():用于套接字初始化. Bind():将 socket 与本机上的一个端口绑定,就可以在该端口监听服务请求. Listen():使socket处于被动的监听模式,并为该  socket  建立一个输入数据队列,将到达的服务器, 请求保存在此队列中,直到程序处理他们. Accept():让服务器接收客户的连接请求. Connect():客户端使用connect函数来配置 socket并与远端服务器建立一个 TCP 连接. Clos

Linux下TCP网络编程与基于Windows下C#socket编程之间通信

一.linux下TCP网络编程基础,需要了解相关函数 Socket():用于套接字初始化. Bind():将 socket 与本机上的一个端口绑定,就可以在该端口监听服务请求. Listen():使socket处于被动的监听模式,并为该  socket  建立一个输入 数据队列,将到达的服务器, 请求保存在此队列中,直到程序处理他们. Accept():让服务器接收客户的连接请求. Connect():客户端使用connect函数来配置 socket并与远端服务器建立一个 TCP 连接. Clo

利用命名管道实现进程间的通信(简单聊天程序的实现)

管道的本质是一种文件,通常是指把一个进程的输出直接传递给另一个进程的输入. 命名管道(named pipe)是一种特殊的文件类型(FIFO文件),它在文件系统中以文件名的形式存在. 下面是Linux中命名管道的文件格式: 通过命令行创建命名管道可以通过mkfifo命令,函数调用如下所示: 1 #include <sys/types.h> 2 #include <sys/stat.h> 3 4 int mkfifo(const char *filename,mode_t mode);

Linux下使用Eclipse开发Hadoop应用程序

在前面一篇文章中介绍了如果在完全分布式的环境下搭建Hadoop0.20.2,现在就再利用这个环境完成开发. 首先用hadoop这个用户登录linux系统(hadoop用户在前面一篇文章中创建的),然后下载eclipse的tar.gz包到/home/hadoop/这个目录下,直接解压缩,于是就会存在/home/hadoop/eclipse这个目录.在开发之前需要将hadoop0.20.2目录下面的一个jar复制到eclipse下面去.(注:在上一篇文章中我将hadoop0.20.2文件夹修改成了h