socket 实现即时通信

本文详细介绍了基于TCP的Socket通信原理及其实现过程,包括服务器端与客户端的建立连接、发送与接收数据的方法,并探讨了如何通过多线程实现双向通信。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于TCP的socket通信的流程是:

server:

1.建立套接字句柄:int sock_handle=socket(AF_INET,SOCK_STREAM,0);

2.bind ip地址:

struct sockaddr_in ser_addr;

ser_addr.sin_family=AF_INET;

ser_addr.sin_addr.s_addr=inet_addr("127.0.0.1");

ser_addr.sin_port=htons(6000);

bind(sock_handle,(struct sockaddr *)&ser_addr,sizeof(struct sockaddr);

3.监听:listen(socket_handle,10);

4.接收请求:

struct sockaddr_in client;

int sock_tmp;

sock_tmp=accept(socket_handle,(struct sockaddr *)&client,sizeof(struct sockaddr));

5.

接收消息或者发送消息:

send(sock_tmp,buf,len(buf),0);

recv(sock_tmp,buf,len(buf),0);


6.close socket

client:

1.建立套接字:

int sock_handle=socket(AF_INET,SOCK_STREAM,0);


2.连接server:

struct sockaddr_in ser_addr;
ser_addr.sin_family=AF_INET;
ser_addr.sin_port=htons(6000);
ser_addr.sin_addr.s_addr=inet_addr("127.0.0.1");

connect(sock_handle,(struct sockaddr *)&ser_addr,sizeof(struct sockaddr));

3.接收消息或者发送消息:

send(sock_handle,buf,len(buf),0);

recv(sock_handle,buf,len(buf),0);

4.close socket.

如果server永远是recv,client 永远是send, 那么随时通信该如何实现呢?

accept和connect实行阻塞模式。(accept()会一直等下去,connect()在windows下会等1-2秒,linux下会稍长些,5-6秒)

只能是server:accept()---->client:connect().(send(),recv()),(send,recv()).......这样似乎也可以保持通话。

想过这样(server:accept()---->client:connect.send(),recv()),(server:accept()---->client:connect().send(),recv())...根本不行,因为已经建立了连接,如果不断开的话,再次连接肯定就不行了。如果close(),断开连接,那么套接字句柄就不存在了,又要建立句柄,那有什么意义呢?

综上,还是一连一接在重复的收发消息比较好。

但是这样,服务器只能接受消息了。

如果要实现两端随时收发消息。

感觉还是用多线程比较合适。

既然双方互相通信的话,就没有什么客户端服务器了。

每个用户绑定一个ip,绑定完了后想对谁发信息,就connect谁就可以了。

这里面还存在一个需要注意的一点。

如果单单测试的话最好每个先开启所有用户的ip绑定.

下面为我的代码:

windows:

#include<winsock.h>
#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include <stdlib.h>
#pragma comment( lib, "ws2_32.lib" )
int id[100];
char start[10];
struct node
{
	int socket_server;
	int socket_client;
};
DWORD WINAPI recvBuf(void *arg)
{
	char buf[30];
	int ans=1;
	int socket_tmp=((node *)arg)->socket_client;
	while(1)
	{
		ans=recv(socket_tmp,buf,30,0);
		if(ans!=0&&ans!=-1)
			printf("%s\n",buf);
	}
}
void* sendBuf(void *arg)
{
	int socket_server=((node *)arg)->socket_server;
	while(1)
	{
		char buf[30];
		scanf("%s",buf);
		send(socket_server,buf,30,0);
	}
}
int main()
{
	WSADATA WSAData;
	if( WSAStartup( MAKEWORD( 1, 1 ), &WSAData ) )//初始化
	{
		printf( "initializationing error!\n" );
		WSACleanup( );
		exit( 0 );
	}
	int socket_server;
	socket_server=socket(AF_INET,SOCK_STREAM,0);
	if(socket_server==-1)
	{
		perror("socket() error\n");
		exit(1);
	}
	struct sockaddr_in seraddr;
	seraddr.sin_family=AF_INET;
	seraddr.sin_port=htons(6001);
	seraddr.sin_addr.s_addr=inet_addr("192.168.1.132");
	int ans=bind(socket_server,(struct sockaddr*)&seraddr,sizeof(struct sockaddr));
	if(ans==-1)
	{
		perror("bind error\n");
		exit(1);
	}
	ans=listen(socket_server,10);
	if(ans==-1)
	{
		perror("listen  error\n");
		exit(1);
	}
	scanf("%s",start);// scanf any string to start
	int socket_my;
	socket_my=socket(AF_INET,SOCK_STREAM,0);
	if(socket_my==-1)
	{
		perror("socket() error\n");
		exit(1);
	}
	//setsockopt(socket_my,SOL_SOCKET,SO_ACCEPTCONN,(const char*)&bconn,sizeof(bool));
	struct sockaddr_in seraddr1;
	seraddr1.sin_family=AF_INET;
	seraddr1.sin_port=htons(6000);
	seraddr1.sin_addr.s_addr=inet_addr("127.0.0.1");
	if(connect(socket_my,(struct sockaddr*)&seraddr1,sizeof(struct sockaddr))<0)
	{
		perror("connect error\n");
		//exit(1);
	}
	int i=0;
	node *arg_send=new node;
	arg_send->socket_server=socket_my;
	CreateThread(NULL,NULL,recvBuf,(void *)arg_send,NULL,(LPDWORD)&id[i]);
	i++;
	while(1)
	{
		int socket_tmp;
		struct sockaddr_in client;
		int len=sizeof(struct sockaddr_in);
		socket_tmp=accept(socket_server,(struct sockaddr*)&client,&len);
		if(socket_tmp<0)
		{
			perror("accept  error\n");
			exit(1);
		}
		node *arg_recv=new node;
		arg_recv->socket_client=socket_tmp;
		CreateThread(NULL,NULL,recvBuf,(void *)arg_recv,NULL,(LPDWORD)&id[i]);
		i++;
		// close(socket_tmp);
	}
	closesocket(socket_server);
}


linux:

 client1(10.0.2.15:5000)

#include<sys/socket.h>
#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<unistd.h>
#include <stdlib.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<pthread.h>
char start[10];
struct node
{
    int socket_server;
    int socket_client;
};
pthread_t id[100];
void *recvBuf(void *arg)
{
    char buf[30];
    int ans=1;
    int socket_tmp=((node *)arg)->socket_client;
    while(1)
    {
        ans=recv(socket_tmp,buf,30,0);
        if(ans!=0)
            printf("%s\n",buf);
    }
}
void *sendBuf(void *arg)
{
    int socket_server=((node *)arg)->socket_server;
    while(1)
    {
        char buf[30];
        scanf("%s",buf);
        send(socket_server,buf,30,0);
    }
}
int main()
{
    int socket_server;
    socket_server=socket(AF_INET,SOCK_STREAM,0);
    if(socket_server==-1)
    {
        perror("socket() error\n");
        exit(1);
    }
    struct sockaddr_in seraddr;
    seraddr.sin_family=AF_INET;
    seraddr.sin_port=htons(5000);
    seraddr.sin_addr.s_addr=inet_addr("10.0.2.15");
    int ans=bind(socket_server,(struct sockaddr*)&seraddr,sizeof(struct sockaddr));
    if(ans==-1)
    {
        perror("bind error\n");
        exit(1);
    }
    ans=listen(socket_server,10);
    if(ans==-1)
    {
        perror("listen  error\n");
        exit(1);
    }
    scanf("%s",start);//scanf any string to start
    int socket_my;
    socket_my=socket(AF_INET,SOCK_STREAM,0);
    if(socket_my==-1)
    {
        perror("socket() error\n");
        exit(1);
    }
    //setsockopt(socket_my,SOL_SOCKET,SO_ACCEPTCONN,(const char*)&bconn,sizeof(bool));
    struct sockaddr_in seraddr1;
    seraddr1.sin_family=AF_INET;
    seraddr1.sin_port=htons(6000);
    seraddr1.sin_addr.s_addr=inet_addr("127.0.0.1");
    if(connect(socket_my,(struct sockaddr*)&seraddr1,sizeof(struct sockaddr))<0)
    {
        perror("connect error\n");
        exit(1);
    }
    int i=0;
    node *arg_send=new node;
    arg_send->socket_server=socket_my;
    pthread_create(&id[i],NULL,sendBuf,(void *)arg_send);
    i++;
    while(1)
    {
        int socket_tmp;
        struct sockaddr_in client;
        socklen_t len=sizeof(struct sockaddr_in);
        socket_tmp=accept(socket_server,(struct sockaddr*)&client,&len);
        if(socket_tmp<0)
        {
            perror("accept  error\n");
            exit(1);
        }
        node *arg_recv=new node;
        arg_recv->socket_client=socket_tmp;
        pthread_create(&id[i],NULL,recvBuf,(void *)arg_recv);
        i++;
        //  close(socket_tmp);
    }

    close(socket_server);
}


client(127.0.0.1:6000)

#include<sys/socket.h>
#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<unistd.h>
#include <stdlib.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<pthread.h>
char start[10];
struct node
{
    int socket_server;
    int socket_client;
};
pthread_t id[100];
void *recvBuf(void *arg)
{
    char buf[30];
    int ans=1;
    int socket_tmp=((node *)arg)->socket_client;
    while(1)
    {
        ans=recv(socket_tmp,buf,30,0);
        if(ans!=0&&ans!=-1)
            printf("%s\n",buf);
    }
}
void *sendBuf(void *arg)
{
    int socket_server=((node *)arg)->socket_server;
    while(1)
    {
        char buf[30];
        scanf("%s",buf);
        send(socket_server,buf,30,0);
    }
}
int main()
{
    int socket_server;
    socket_server=socket(AF_INET,SOCK_STREAM,0);
    if(socket_server==-1)
    {
        perror("socket() error\n");
        exit(1);
    }
    struct sockaddr_in seraddr;
    seraddr.sin_family=AF_INET;
    seraddr.sin_port=htons(6000);
    seraddr.sin_addr.s_addr=inet_addr("127.0.0.1");
    int ans=bind(socket_server,(struct sockaddr*)&seraddr,sizeof(struct sockaddr));
    if(ans==-1)
    {
        perror("bind error\n");
        exit(1);
    }
    ans=listen(socket_server,10);
    if(ans==-1)
    {
        perror("listen  error\n");
        exit(1);
    }
    scanf("%s",start);// scanf any string to start
    int socket_my;
    socket_my=socket(AF_INET,SOCK_STREAM,0);
    if(socket_my==-1)
    {
        perror("socket() error\n");
        exit(1);
    }
    //setsockopt(socket_my,SOL_SOCKET,SO_ACCEPTCONN,(const char*)&bconn,sizeof(bool));
    struct sockaddr_in seraddr1;
    seraddr1.sin_family=AF_INET;
    seraddr1.sin_port=htons(5000);
    seraddr1.sin_addr.s_addr=inet_addr("10.0.2.15");
    if(connect(socket_my,(struct sockaddr*)&seraddr1,sizeof(struct sockaddr))<0)
    {
        perror("connect error\n");
        exit(1);
    }
    int i=0;
    node *arg_send=new node;
    arg_send->socket_server=socket_my;
    pthread_create(&id[i],NULL,sendBuf,(void *)arg_send);
    i++;
    while(1)
    {
        int socket_tmp;
        struct sockaddr_in client;
        socklen_t len=sizeof(struct sockaddr_in);
        socket_tmp=accept(socket_server,(struct sockaddr*)&client,&len);
        if(socket_tmp<0)
        {
            perror("accept  error\n");
            exit(1);
        }
        node *arg_recv=new node;
        arg_recv->socket_client=socket_tmp;
        pthread_create(&id[i],NULL,recvBuf,(void *)arg_recv);
        i++;
        // close(socket_tmp);
    }

    close(socket_server);
}

 



                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值