linux 的 socket例子

server端:

#include <stdio.h>
#include <string.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <syslog.h>
#include <errno.h>
#include <pthread.h>
#define MAX_LISTEN_NUM 5
#define SEND_BUF_SIZE 100
#define RECV_BUF_SIZE 100
#define LISTEN_PORT 2010
#define MAX_CLIENT_NUM 10
typedef struct _tagclientParam{
	fd_set fset;
	int fd;
	int port;
	char ipV4Addr[20];
}clientParam;


void* client_thread(void* param);

int main()
{
	int listen_sock = 0,maxFd = 0 ;
	int ret =0,wrSockIndex =0,i=0;
	int wr_sock[MAX_LISTEN_NUM] = {0};
	struct sockaddr_in hostaddr;
	struct sockaddr_in clientaddr;
	int socklen = sizeof(clientaddr);
	char sendbuf[SEND_BUF_SIZE] = {0};
	char recvbuf[RECV_BUF_SIZE] = {0};
	int sendlen = 0;
	int recvlen = 0;
	int retlen = 0;
	int leftlen = 0;
	char *ptr = NULL;
	pthread_t ptid[MAX_CLIENT_NUM] ;
	fd_set serverRFSet,serverSokctSet;
	  
	memset((void *)&hostaddr, 0, sizeof(hostaddr));
	memset((void *)&clientaddr, 0, sizeof(clientaddr));
	hostaddr.sin_family = AF_INET;
	hostaddr.sin_port = htons(LISTEN_PORT);
	hostaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	  
	FD_ZERO(&serverRFSet); //clear rdfds
	FD_ZERO(&serverSokctSet); //clear rdfds
  
	listen_sock = socket(AF_INET, SOCK_STREAM, 0);
	if(listen_sock < 0)
	{
		syslog(LOG_ERR, "%s:%d, create socket failed", __FILE__, __LINE__);
		exit(1);
	}
	FD_SET(listen_sock, &serverSokctSet); //add stdin handle into rdfds
	
	if((ret=bind(listen_sock, (struct sockaddr *)&hostaddr, sizeof(hostaddr))) < 0)
	{
		printf("bind error code: %d \n",ret);
		syslog(LOG_ERR, "%s:%d, bind socket failed", __FILE__, __LINE__);
		exit(1);
	}
	if((ret=listen(listen_sock, MAX_LISTEN_NUM)) < 0)
	{
		syslog(LOG_ERR, "%s:%d, listen failed", __FILE__, __LINE__);
		exit(1);
	}
	

	while(1){
		
		maxFd = listen_sock +1;
		ret = select(maxFd,&serverSokctSet,NULL,NULL,NULL);
		switch(ret){
			case 0: break;
			
			case -1:{
			}break;
			
			default: {

				if(FD_ISSET(listen_sock,&serverSokctSet)){
					if(wrSockIndex < MAX_CLIENT_NUM){
						wr_sock[wrSockIndex] = accept(listen_sock, (struct sockaddr *)&clientaddr, &socklen);
						FD_SET(wr_sock[wrSockIndex], &serverRFSet); //add stdin handle into rdfds
						ptr  = inet_ntoa(clientaddr.sin_addr) ; 
						sprintf(sendbuf, "welcome %s:%d here!", ptr, clientaddr.sin_port);
						sendlen = strlen(sendbuf) +1;
						retlen = send(wr_sock[wrSockIndex], sendbuf, sendlen, 0);
						if(retlen < 0){
							printf("send error \n"); 
						}
						clientParam cparm;
						存在cparm资源被覆盖的情况,独立变量或者锁
						memcpy(cparm.ipV4Addr,ptr,20);
						cparm.port = clientaddr.sin_port;
						cparm.fd = wr_sock[wrSockIndex];
						cparm.fset = serverRFSet;
						if(0 != pthread_create(&ptid[wrSockIndex],NULL,client_thread,(void*)(&cparm)) ){
							printf("carete error !\n");
						}
						wrSockIndex++;
					}
				}
			}break;	
		}
	}
	for(i=0;i<wrSockIndex;i++)
		close(wr_sock[i]);
	close(listen_sock);
  
  return 0;
  
}
//一问一答,应该读和写分开两个线程,not do it now!!!
void* client_thread(void* param){
	char recvbuf[RECV_BUF_SIZE] = {0};
	int sendlen = 0;
	int recvlen = 0;
	int retlen = 0;
	int leftlen = 0;
	char *ptr = NULL;
	int maxFd,ret;
	clientParam *cparm  = (clientParam *)param;
	maxFd = cparm->fd +1;
	while(1){
		ret = select(maxFd,&cparm->fset,NULL,NULL,NULL);
		switch(ret){
			case 0: break;
			
			case -1:{

			}break;

			default: {
				if(FD_ISSET(cparm->fd,&cparm->fset)){

					recvlen = 0;
					retlen = 0;
					ptr = recvbuf;
					leftlen = RECV_BUF_SIZE -1;
					retlen = recv(cparm->fd, ptr, leftlen, 0) ;
					printf("from %s:%d  message: \n",cparm->ipV4Addr,cparm->port);
					printf("--->%s\n", ptr);
					printf("please input data \n--->");
					//scanf("%s",ptr);//不接受空格
					gets(ptr);//it is dangerous !!!
					if(strcmp("quit",ptr) == 0) goto __end;
					sendlen = strlen(ptr) +1;
					retlen = send(cparm->fd, ptr, sendlen, 0);
					if(retlen < 0)
					{
						if(errno == EINTR)
						retlen = 0;
						else
						exit(1);
					}	 
				}
			}
			break;	
		}
	}
__end:
		close(cparm->fd);
}

clien端:

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <syslog.h>
#include <errno.h>
#include <stdlib.h>
#define MAX_LISTEN_NUM 5
#define SEND_BUF_SIZE 100
#define RECV_BUF_SIZE 100
#define SERVER_PORT 2010
int main()
{
    int sock_fd = 0,maxFd;
    char recvbuf[RECV_BUF_SIZE] = {0};
    char sendbuf[SEND_BUF_SIZE] = {0};
    int recvlen = 0;
    int retlen = 0;
    int sendlen = 0;
    int leftlen = 0;
    char *ptr = NULL;
    struct sockaddr_in ser_addr;
    fd_set clientFSet;
	
    memset(&ser_addr, 0, sizeof(ser_addr));
    ser_addr.sin_family = AF_INET;
    inet_aton("192.168.1.100", (struct in_addr *)&ser_addr.sin_addr);
    ser_addr.sin_port = htons(SERVER_PORT);
    sock_fd = socket(AF_INET, SOCK_STREAM, 0);
	
    FD_ZERO(&clientFSet); //clear rdfds
    FD_SET(sock_fd, &clientFSet); //add stdin handle into rdfds

    if(sock_fd < 0)
    {
        syslog(LOG_ERR, "%s:%d, create socket failed", __FILE__, __LINE__);
        exit(1);
    }
    if(connect(sock_fd, (struct sockaddr *)&ser_addr, sizeof(ser_addr)) < 0)
    {
        syslog(LOG_ERR, "%s:%d, connect socket failed", __FILE__, __LINE__);
        exit(1);
    }
	maxFd = sock_fd+1;
	while(1)
	{
		//描述符最大值加1 
		 //receive data
		switch(select(maxFd,&clientFSet,NULL,NULL,NULL)){
			case 0: break;
			case -1:{
				printf("server is out \n");
				goto __end__;
			} break;
			default: {
				if(FD_ISSET(sock_fd,&clientFSet)){
					recvlen = 0;
					retlen = 0;
					ptr = recvbuf;
					leftlen = RECV_BUF_SIZE -1;
					retlen = recv(sock_fd, ptr, leftlen, 0);
					printf("Receive date:\n%s \n", ptr);
					printf("please input data \n");
					//scanf("%s",ptr);//不接受空格
					gets(ptr);//it is dangerous !!!
					//printf("\nipnut data:%s \n",ptr);
					sendlen = strlen(ptr) +1;
					retlen = send(sock_fd, ptr, sendlen, 0);
					if(retlen < 0)
					{
						if(errno == EINTR)
						retlen = 0;
						else
						exit(1);
					}
				}
			}
			break;
		}	
	}
__end__:
    close(sock_fd);
    
}

bug:

1、多个client连接server出现server不响应!

2、对于每个程序来说,读取和写需要分开两个线程来实现

仅仅是测试的例子,部分代码摘抄网络!!!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

john_liqinghan

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

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

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

打赏作者

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

抵扣说明:

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

余额充值