socket简单多线程方式

socket 需要的过程

  1. 通过系统调用socket来创建一个socket

  2. 通过bind()来绑定一个端口,并且指定相应的ip类型及通讯方式

  3. 通过调用listen()监听端口的连接

  4. 调用accept()来等待用户的连接,当调用这个函数的时候系统会堵塞直到有相应的客户端连接。

头文件说明

#include<sys/types.h>

该头文件定义了socket的数据类型,后面的两个头文件需要包含这个头文件

#include <sys/socket.h>

包含了一些socket所需的结构定义

#include <netinet/in.h>

该类的是定义了一些所需要的互联网域名地址常量和结构。

void error(char *msg)

该类其实是将错误代码输出成文字的信息,在linux c当中所有的错误都有一个特定的errno的,当出现错误的时候可以查看相应的编写来定位问题的原因,后面附录错误的编号

代码

    #include <arpa/inet.h>
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <string.h>
    #include <pthread.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <unistd.h>
    void* socketProcess(void* socket_desc );

    int main(int argc, char const* argv[])
    {
        int sock_desc,c,recv_len;
        int *new_sock;
        char client_message[512];
        struct sockaddr_in server,client;
        **//#define AF_INET     2       /* internetwork: UDP, TCP, etc. */**
        sock_desc=socket(AF_INET,SOCK_STREAM,0);
        if(sock_desc<0){
            puts("错误");
            return 1;
        }
        server.sin_addr.s_addr=INADDR_ANY;
        server.sin_port=htons(8888);
        server.sin_family=AF_INET;
        if(bind(sock_desc,(struct sockaddr*)&server,sizeof(server))<0){
            puts("绑定错误");
        }
        puts("绑定完成");


        listen(sock_desc,5);
        puts("正在监听等待连接");


        while(1){
            new_sock=(int*)malloc(sizeof(int));
            *new_sock=accept(sock_desc,(struct sockaddr*)&client,(socklen_t* )&c);
            pthread_t thread_id;
            puts("接受请求");
            if(*new_sock!=-1){
                char ipv4addr[100];
                 char addr_buf[INET_ADDRSTRLEN];
                 socklen_t len;
                 if(getsockname(*new_sock,(struct sockaddr*)&client,&len)==-1)
                 {
                     perror("gesockname err");
                 }
                 printf("ip:%d\n",ntohs(client.sin_port));
                if(pthread_create(&thread_id,0,&socketProcess,(void*)new_sock)<0){//创建一个线程
                    perror("创建线程失败");
                    return 1;
                }
                pthread_detach(thread_id);//线程分离
            }
            puts("新客户连接");

        }
        puts("连接成功");
        return 0;
    }
    void* socketProcess(void* socket_desc ){
     int *csock = (int*)socket_desc;
         char buffer[1024];
         int buffer_len = 1024;
         int bytecount;

         while(1){
             memset(buffer, 0, buffer_len);
             if((bytecount = recv(*csock, buffer, buffer_len, 0))== -1){
                 fprintf(stderr, "接收数据错误,错误代码: %d\n", errno);
                 close(*csock);
                 return(0);
             }
             printf("接收到字节数 %d\n接收字符串 \"%s\"\n", bytecount, buffer);
             strcat(buffer, " SERVER ECHO\n");

             if((bytecount = send(*csock, buffer, strlen(buffer), 0))== -1){
                 fprintf(stderr, "错误发送数据 %d\n", errno);
                 close(*csock);
                 return(0);
             }

             printf("发送字节数 %d\n", bytecount);
         }
         return 0;
    }

常用的错误编号

#define EPERM       1       /* Operation not permitted */
#define ENOENT      2       /* No such file or directory */
#define ESRCH       3       /* No such process */
#define EINTR       4       /* Interrupted system call */
#define EIO     5       /* Input/output error */
#define ENXIO       6       /* Device not configured */
#define E2BIG       7       /* Argument list too long */
#define ENOEXEC     8       /* Exec format error */
#define EBADF       9       /* Bad file descriptor */
#define ECHILD      10      /* No child processes */
#define EDEADLK     11      /* Resource deadlock avoided */
                    /* 11 was EAGAIN */
#define ENOMEM      12      /* Cannot allocate memory */
#define EACCES      13      /* Permission denied */
#define EFAULT      14      /* Bad address */
#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL
#define ENOTBLK     15      /* Block device required */
#endif
#define EBUSY       16      /* Device / Resource busy */
#define EEXIST      17      /* File exists */
#define EXDEV       18      /* Cross-device link */
#define ENODEV      19      /* Operation not supported by device */
#define ENOTDIR     20      /* Not a directory */
#define EISDIR      21      /* Is a directory */
#define EINVAL      22      /* Invalid argument */
#define ENFILE      23      /* Too many open files in system */
#define EMFILE      24      /* Too many open files */
#define ENOTTY      25      /* Inappropriate ioctl for device */
#define ETXTBSY     26      /* Text file busy */
#define EFBIG       27      /* File too large */
#define ENOSPC      28      /* No space left on device */
#define ESPIPE      29      /* Illegal seek */
#define EROFS       30      /* Read-only file system */
#define EMLINK      31      /* Too many links */
#define EPIPE       32      /* Broken pipe */

/* math software */
#define EDOM        33      /* Numerical argument out of domain */
#define ERANGE      34      /* Result too large */

/* non-blocking and interrupt i/o */
#define EAGAIN      35      /* Resource temporarily unavailable */
#define EWOULDBLOCK EAGAIN      /* Operation would block */
#define EINPROGRESS 36      /* Operation now in progress */
#define EALREADY    37      /* Operation already in progress */

/* ipc/network software -- argument errors */
#define ENOTSOCK    38      /* Socket operation on non-socket */
#define EDESTADDRREQ    39      /* Destination address required */
#define EMSGSIZE    40      /* Message too long */
#define EPROTOTYPE  41      /* Protocol wrong type for socket */
#define ENOPROTOOPT 42      /* Protocol not available */
#define EPROTONOSUPPORT 43      /* Protocol not supported */
#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL
#define ESOCKTNOSUPPORT 44      /* Socket type not supported */
#endif
#define ENOTSUP     45      /* Operation not supported */
#if !__DARWIN_UNIX03 && !defined(KERNEL)
/*
 * This is the same for binary and source copmpatability, unless compiling
 * the kernel itself, or compiling __DARWIN_UNIX03; if compiling for the
 * kernel, the correct value will be returned.  If compiling non-POSIX
 * source, the kernel return value will be converted by a stub in libc, and
 * if compiling source with __DARWIN_UNIX03, the conversion in libc is not
 * done, and the caller gets the expected (discrete) value.
 */
#define EOPNOTSUPP   ENOTSUP    /* Operation not supported on socket */
#endif /* !__DARWIN_UNIX03 && !KERNEL */

#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL
#define EPFNOSUPPORT    46      /* Protocol family not supported */
#endif
#define EAFNOSUPPORT    47      /* Address family not supported by protocol family */
#define EADDRINUSE  48      /* Address already in use */
#define EADDRNOTAVAIL   49      /* Can't assign requested address */

/* ipc/network software -- operational errors */
#define ENETDOWN    50      /* Network is down */
#define ENETUNREACH 51      /* Network is unreachable */
#define ENETRESET   52      /* Network dropped connection on reset */
#define ECONNABORTED    53      /* Software caused connection abort */
#define ECONNRESET  54      /* Connection reset by peer */
#define ENOBUFS     55      /* No buffer space available */
#define EISCONN     56      /* Socket is already connected */
#define ENOTCONN    57      /* Socket is not connected */
#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL
#define ESHUTDOWN   58      /* Can't send after socket shutdown */
#define ETOOMANYREFS    59      /* Too many references: can't splice */
#endif
#define ETIMEDOUT   60      /* Operation timed out */
#define ECONNREFUSED    61      /* Connection refused */

#define ELOOP       62      /* Too many levels of symbolic links */
#define ENAMETOOLONG    63      /* File name too long */

/* should be rearranged */
#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL
#define EHOSTDOWN   64      /* Host is down */
#endif
#define EHOSTUNREACH    65      /* No route to host */
#define ENOTEMPTY   66      /* Directory not empty */

/* quotas & mush */
#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL
#define EPROCLIM    67      /* Too many processes */
#define EUSERS      68      /* Too many users */
#endif
#define EDQUOT      69      /* Disc quota exceeded */

/* Network File System */
#define ESTALE      70      /* Stale NFS file handle */
#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL
#define EREMOTE     71      /* Too many levels of remote in path */
#define EBADRPC     72      /* RPC struct is bad */
#define ERPCMISMATCH    73      /* RPC version wrong */
#define EPROGUNAVAIL    74      /* RPC prog. not avail */
#define EPROGMISMATCH   75      /* Program version wrong */
#define EPROCUNAVAIL    76      /* Bad procedure for program */
#endif

#define ENOLCK      77      /* No locks available */
#define ENOSYS      78      /* Function not implemented */

#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL
#define EFTYPE      79      /* Inappropriate file type or format */
#define EAUTH       80      /* Authentication error */
#define ENEEDAUTH   81      /* Need authenticator */

/* Intelligent device errors */
#define EPWROFF     82  /* Device power is off */
#define EDEVERR     83  /* Device error, e.g. paper out */
#endif

#define EOVERFLOW   84      /* Value too large to be stored in data type */

/* Program loading errors */
#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL
#define EBADEXEC    85  /* Bad executable */
#define EBADARCH    86  /* Bad CPU type in executable */
#define ESHLIBVERS  87  /* Shared library version mismatch */
#define EBADMACHO   88  /* Malformed Macho file */
#endif

#define ECANCELED   89      /* Operation canceled */

#define EIDRM       90      /* Identifier removed */
#define ENOMSG      91      /* No message of desired type */   
#define EILSEQ      92      /* Illegal byte sequence */
#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL
#define ENOATTR     93      /* Attribute not found */
#endif

#define EBADMSG     94      /* Bad message */
#define EMULTIHOP   95      /* Reserved */
#define ENODATA     96      /* No message available on STREAM */
#define ENOLINK     97      /* Reserved */
#define ENOSR       98      /* No STREAM resources */
#define ENOSTR      99      /* Not a STREAM */
#define EPROTO      100     /* Protocol error */
#define ETIME       101     /* STREAM ioctl timeout */

#if __DARWIN_UNIX03 || defined(KERNEL)
/* This value is only discrete when compiling __DARWIN_UNIX03, or KERNEL */
#define EOPNOTSUPP  102     /* Operation not supported on socket */
#endif /* __DARWIN_UNIX03 || KERNEL */

#define ENOPOLICY   103     /* No such policy registered */

#if __DARWIN_C_LEVEL >= 200809L
#define ENOTRECOVERABLE 104     /* State not recoverable */
#define EOWNERDEAD      105     /* Previous owner died */
#endif

#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL
#define EQFULL      106     /* Interface output queue is full */
#define ELAST       106     /* Must be equal largest errno */
#endif

#endif /* _SYS_ERRNO_H_ */

转载于:https://my.oschina.net/u/215677/blog/619082

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
多线程聊天是一种基于Socket编程的方式,可以实现多个客户端与服务器之间的即时通讯。在这种模型中,服务器端需要支持多线程来处理多个客户端的请求。 以下是一个基本的多线程聊天程序的示例代码: ```python import socket import threading # 为每个客户端创建一个线程 def handle_client(client_socket): while True: # 接收客户端发送的数据 data = client_socket.recv(1024).decode() # 处理数据 # 在这里可以添加自定义的逻辑 # 发送响应给客户端 client_socket.send("Message received".encode()) # 关闭客户端连接 client_socket.close() def main(): # 创建一个TCP socket对象 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 绑定服务器地址和端口 server_address = ('localhost', 8888) server_socket.bind(server_address) # 开始监听客户端连接 server_socket.listen(5) print("Server started, listening on", server_address) while True: # 接受客户端连接 client_socket, client_address = server_socket.accept() print("New connection from", client_address) # 创建一个新的线程处理客户端请求 client_thread = threading.Thread(target=handle_client, args=(client_socket,)) client_thread.start() if __name__ == "__main__": main() ``` 以上代码创建了一个基础的多线程聊天服务器。当有新的客户端连接时,会为每个客户端创建一个新的线程处理其请求。详细的逻辑可以根据实际需求进行定制。 值得注意的是,这只是一个简单的示例,实际应用中还需要进行错误处理、数据验证等更多的工作。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值