LINUX TCP/IP socket通信4

经过了一个多星期的学习,我在这里总结一下关于Linux,Windows的socket TCP通信的不同情形。

  1. server,client之间的通信
    https://blog.csdn.net/wesigj/article/details/99294538

  2. Socket之TCP全双工Server-Client通信
    https://blog.csdn.net/wesigj/article/details/99322695

  3. client,client之间的通信

  4. 一个小应用-------网络聊天室https://blog.csdn.net/wesigj/article/details/99418596

  5. Linux与Windows之间的socket通信

  6. socket实现两台pc之间的数据传输功能,包括windows到linux,TCP/IP

三、聊天室的应用

实际上,client与client之间的通信是可以用一个两个人的聊天室来替代的。在我的认识中,client与client之间应该需要一个服务器来控制收发信息,那么就是server接收两个client之后,通过recv与send函数来发送接收信息。

	其实,使用多线程也是一种合适的方法,使用fork函数,创建子线程,来send和recv。
	或者使用read函数,和write函数来send recv
	fgets 和 fputs函数 来通信
	按正常来说,我们应该是使用send函数和recv函数来通信,其他的比较投机取巧。

server

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>


#define PORT 8000
#define MAX_MAN 20
#define MAX_BUFFER_SIZE 128

int sockfd;
int connectfd[MAX_MAN];

//define DEBUG_PRINT 
#ifdef DEBUG_PRINT
#define DEBUG(format, ...) printf("FILE: "__FILE__"), LINE: %d: "format"\n", __LINE__, ##__VA_ARGS__)
#else
#define DEBUG(format, ...)
#endif

void quit();
void recv_send(int numble);

int main(int argc, char const *argv[])
{

	char server_buff[MAX_BUFFER_SIZE];
	time_t ticks;
	int i;	
	pthread_t thread;
	struct sockaddr_in server_addr,client_addr;	


	printf("waiting for connect\n(enter ""exit"" to quit)");
	//define addr

	DEBUG("=== initialize...");

	memset(&server_addr,0,sizeof(struct sockaddr_in));
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(PORT);
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

	DEBUG("=== socket...");
	//define sockfd
	sockfd = socket(AF_INET,SOCK_STREAM,0);
	if (sockfd< 0)
	{
		perror("socket");
		exit(1);
	}

	DEBUG("=== bind...");
	if(bind(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr)) < 0)
	{
		perror("bind");
		exit(1);
	}

	DEBUG("=== listening...");
	listen(sockfd,MAX_MAN);

	//pthread_create QUIT

	pthread_create(&thread,NULL,(void *)(quit),NULL);

	memset(&connectfd,-1,sizeof(connectfd));



	while(1)
	{
		int length;
		for(i=0;i<MAX_MAN;i++)
		{
			if(connectfd[i] == -1)
				break;
		}
		connectfd[i] = accept(sockfd, (struct sockaddr *)&client_addr,&length);
		if(connectfd[i] < 0)
		{
			perror("accept");

		}
		ticks = time(NULL);

		printf("%.24s\n\tconnect from : %s,port %d\n",
														ctime(&ticks),
														inet_ntop(AF_INET,&(client_addr.sin_addr),server_buff,MAX_BUFFER_SIZE ),
														ntohs(client_addr.sin_port)
														);
		//pthread_create  recv send

		pthread_create(malloc(sizeof(pthread_t)),NULL,(void *)(&recv_send),(void *)i);

	}

	return 0;
}


void quit()
{
	char message[10];
	while(1)
	{
		scanf("%s",message);
		if(strcmp(message, "quit") == 0)
		{
			printf("goodbye everyome\n");
			close(sockfd);
			exit(0);
		}
	}
}

void recv_send(int numble)
{
    int len, i;
    char name[32], mytime[32], buf[MAX_BUFFER_SIZE];
    time_t ticks;
    int ret;

      // 获取此线程对应的套接字用户的名字
    write(connectfd[numble], "your name: ", strlen("your name: "));
    len = read(connectfd[numble], name, 32);
    if(len > 0)
        name[len-1] = '\0';     // 去除换行符
    strcpy(buf, name);
    strcat(buf, "\tjoin in\n\0");
        // 把当前用户的加入 告知所有用户
    for(i=0; i<MAX_MAN; i++)
    {
        if(connectfd[i] != -1)
            write(connectfd[i], buf, strlen(buf));
    }

     while(1)
     {
            char temp[MAX_BUFFER_SIZE];
            if((len=read(connectfd[numble], temp, MAX_BUFFER_SIZE)) > 0)
            {
	            temp[len-1] = '\0';
	            // 当用户输入bye时,当前用户退出
	            if(strcmp(temp, "bye") == 0)
	            {
	            	close(connectfd[numble]);
                 	connectfd[numble] = -1;
                 	pthread_exit(&ret);
	            }
	            ticks = time(NULL);
	            sprintf(mytime, "%.24s\r\n", ctime(&ticks));
	            //write(connfd[n], mytime, strlen(mytime));
	            strcpy(buf, name);
	            strcat(buf, "\t");
	            strcat(buf, mytime);
	            strcat(buf, "\r\t");
	            strcat(buf, temp);
	            strcat(buf, "\n");

	            for(i=0; i<MAX_MAN; i++)
	            {
                    if(connectfd[i] != -1)
                         write(connectfd[i], buf, strlen(buf));
	            }
            }
       }
}

client

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

#define MAX_BUFFER_SIZE 128
#define HOST_IP "127.1.1.0"
#define PORT 8000


void send_message();
int sockfd;

int main(int argc, char const *argv[])
{
    pthread_t thread;
    struct sockaddr_in client_addr;
    char buffer[MAX_BUFFER_SIZE];

    memset(&client_addr,0,sizeof(struct sockaddr_in));
    client_addr.sin_family = AF_INET;
    client_addr.sin_port = htons(PORT);
    client_addr.sin_addr.s_addr = inet_addr(HOST_IP);

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

    printf("connect to server\n");
    if (connect(sockfd, (struct sockaddr *)&client_addr,sizeof(client_addr)) < 0)
    {
        perror("connect");
        exit(1);
    }

    //pthread_create

    pthread_create(&thread,NULL,(void *)(&send_message),NULL);

    while(1)
    {
        int length;
        if((length = read(sockfd,buffer,MAX_BUFFER_SIZE)) > 0)
        {
            buffer[length] = '\0';
            printf("\n%s",buffer );
            fflush(stdout);
        }
    }

    return 0;
}

void send_message()
{
    char name[32];
    char buffer[MAX_BUFFER_SIZE];

    fgets(name,32,stdin);
    write(sockfd,name,strlen(name));
    while(1)
    {
        fgets(buffer,MAX_BUFFER_SIZE,stdin);
        write(sockfd,buffer,strlen(buffer));
        if (strcmp(buffer,"bye\n") == 0)
        {
            exit(0);
        }
    }
}

server

client1
client2

用了差不多一个多星期来学习Linux,socket,TCP通信。对TCP通信有了浅显的了解。在下次的时候,我会将学到的东西总结一下。

参考资料
代码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WeSiGJ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值