tcp server in c

此博客展示了一个TCP服务器程序的代码。代码包含创建套接字、绑定端口、监听连接等操作,还定义了读取数据的函数。通过循环不断接收客户端连接和数据,利用自定义的read_line函数从套接字读取数据,实现了基本的TCP服务器功能。

/* fpont 1/00 */
/* pont.net    */
/* tcpServer.c */

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h> /* close */


#define SUCCESS 0
#define ERROR   1

#define END_LINE 0x0
#define SERVER_PORT 1500
#define MAX_MSG 100

/* function readline */
int read_line();

int main (int argc, char *argv[]) {
 
  int sd, newSd, cliLen;

  struct sockaddr_in cliAddr, servAddr;
  char line[MAX_MSG];


  /* create socket */
  sd = socket(AF_INET, SOCK_STREAM, 0);
   if(sd<0) {
    perror("cannot open socket ");
    return ERROR;
  }
 
  /* bind server port */
  servAddr.sin_family = AF_INET;
  servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
  servAddr.sin_port = htons(SERVER_PORT);
 
  if(bind(sd, (struct sockaddr *) &servAddr, sizeof(servAddr))<0) {
    perror("cannot bind port ");
    return ERROR;
  }

  listen(sd,5);
 
  while(1) {

    printf("%s: waiting for data on port TCP %u/n",argv[0],SERVER_PORT);

    cliLen = sizeof(cliAddr);
    newSd = accept(sd, (struct sockaddr *) &cliAddr, &cliLen);
    if(newSd<0) {
      perror("cannot accept connection ");
      return ERROR;
    }
   
    /* init line */
    memset(line,0x0,MAX_MSG);
   
    /* receive segments */
    while(read_line(newSd,line)!=ERROR) {
     
      printf("%s: received from %s:TCP%d : %s/n", argv[0],
      inet_ntoa(cliAddr.sin_addr),
      ntohs(cliAddr.sin_port), line);
      /* init line */
      memset(line,0x0,MAX_MSG);
     
    } /* while(read_line) */
   
  } /* while (1) */

}


/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING       */
/* this function is experimental.. I don't know yet if it works  */
/* correctly or not. Use Steven's readline() function to have    */
/* something robust.                                             */
/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING       */

/* rcv_line is my function readline(). Data is read from the socket when */
/* needed, but not byte after bytes. All the received data is read.      */
/* This means only one call to recv(), instead of one call for           */
/* each received byte.                                                   */
/* You can set END_CHAR to whatever means endofline for you. (0x0A is /n)*/
/* read_lin returns the number of bytes returned in line_to_return       */
int read_line(int newSd, char *line_to_return) {
 
  static int rcv_ptr=0;
  static char rcv_msg[MAX_MSG];
  static int n;
  int offset;

  offset=0;

  while(1) {
    if(rcv_ptr==0) {
      /* read data from socket */
      memset(rcv_msg,0x0,MAX_MSG); /* init buffer */
      n = recv(newSd, rcv_msg, MAX_MSG, 0); /* wait for data */
      if (n<0) {
 perror(" cannot receive data ");
 return ERROR;
      } else if (n==0) {
 printf(" connection closed by client/n");
 close(newSd);
 return ERROR;
      }
    }
 
    /* if new data read on socket */
    /* OR */
    /* if another line is still in buffer */

    /* copy line into 'line_to_return' */
    while(*(rcv_msg+rcv_ptr)!=END_LINE && rcv_ptr<n) {
      memcpy(line_to_return+offset,rcv_msg+rcv_ptr,1);
      offset++;
      rcv_ptr++;
    }
   
    /* end of line + end of buffer => return line */
    if(rcv_ptr==n-1) {
      /* set last byte to END_LINE */
      *(line_to_return+offset)=END_LINE;
      rcv_ptr=0;
      return ++offset;
    }
   
    /* end of line but still some data in buffer => return line */
    if(rcv_ptr <n-1) {
      /* set last byte to END_LINE */
      *(line_to_return+offset)=END_LINE;
      rcv_ptr++;
      return ++offset;
    }

    /* end of buffer but line is not ended => */
    /*  wait for more data to arrive on socket */
    if(rcv_ptr == n) {
      rcv_ptr = 0;
    }
   
  } /* while */
}
 
 

<think>好的,用户现在想找C#中TcpClient和TcpServer以及与C语言封装的示例代码或教程。我需要结合之前提供的引用内容来帮助他。 首先,用户提到的引用1和2是关于C#的TcpClient和TcpListener的使用,比如引用1中的示例代码展示了如何用TcpClient连接服务器并发送数据。引用2则提到了TcpListener的用法,可以用IP和端口来创建实例。这些可以作为C#部分的基础示例。 然后,用户还提到C语言的封装,引用3和4中有相关的信息。引用3是一个C#的TCP示例程序,虽然语言是C#,但项目地址可能包含有用的资源。而引用4是关于用C语言封装TCP/UDP的代码库,提到了编译共享库的步骤,这可能对用户有帮助。需要确认这些引用中的代码是否符合用户的需求,尤其是C语言部分。 用户的需求是寻找C#和C语言的实例代码或教程。可能需要分别给出C#的服务器和客户端代码,以及C语言封装的示例。同时,用户提到“封装”,可能希望代码模块化,便于重用。 考虑到用户可能需要对比或整合C#和C的代码,应该确保示例清晰,步骤明确。比如,先展示C#的TcpServerTcpClient代码,再展示C语言如何封装TCP通信,并说明如何编译和使用。 另外,用户提供的引用中有C#的示例,但C语言部分可能不够详细。需要补充C语言的服务器和客户端代码,并解释如何封装成库,如引用4中的步骤。可能需要分步骤说明如何编译共享库,如何在C#中调用C语言的库,或者反之,但用户的问题可能更偏向于分别的示例,而不是跨语言调用。 需要检查是否有遗漏,比如C语言中如何使用socket API创建TCP服务器和客户端,然后如何将其封装成库。同时,确保代码示例正确,语法无误,并符合用户的实际应用场景,比如学习或测试目的。 最后,生成相关问题时要围绕TCP通信、封装方法、跨语言通信等方向,帮助用户深入理解。</think>### C#与C语言TCP通信示例对比 #### 一、C#实现TCP通信 1. **TcpServer实现**(使用TcpListener) ```csharp using System.Net; using System.Net.Sockets; TcpListener server = new TcpListener(IPAddress.Any, 8888); server.Start(); TcpClient client = server.AcceptTcpClient(); NetworkStream stream = client.GetStream(); byte[] buffer = new byte[1024]; int bytesRead = stream.Read(buffer, 0, buffer.Length); string data = Encoding.ASCII.GetString(buffer, 0, bytesRead); Console.WriteLine($"接收: {data}"); stream.Write(Encoding.ASCII.GetBytes("ACK")); client.Close(); server.Stop(); ``` 代码特点:使用同步模式,支持ASCII编码通信[^2] 2. **TcpClient实现** ```csharp TcpClient client = new TcpClient(); client.Connect("localhost", 8888); NetworkStream stream = client.GetStream(); byte[] message = Encoding.ASCII.GetBytes("Hello Server"); stream.Write(message, 0, message.Length); byte[] response = new byte[256]; int bytes = stream.Read(response, 0, response.Length); Console.WriteLine($"响应: {Encoding.ASCII.GetString(response, 0, bytes)}"); client.Close(); ``` 代码特点:实现基础请求-响应模型[^1] #### 二、C语言TCP通信封装 1. **封装网络库(network.h)** ```c #ifndef NETWORK_H #define NETWORK_H typedef struct { int sockfd; } TCP_Connection; TCP_Connection tcp_connect(const char* host, int port); int tcp_send(TCP_Connection conn, const char* data, int len); int tcp_receive(TCP_Connection conn, char* buffer, int buffer_size); void tcp_close(TCP_Connection conn); #endif ``` 2. **库实现(network.c)** ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include <unistd.h> #include "network.h" TCP_Connection tcp_connect(const char* host, int port) { struct sockaddr_in server_addr; TCP_Connection conn; conn.sockfd = socket(AF_INET, SOCK_STREAM, 0); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(port); inet_pton(AF_INET, host, &server_addr.sin_addr); connect(conn.sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)); return conn; } int tcp_send(TCP_Connection conn, const char* data, int len) { return send(conn.sockfd, data, len, 0); } int tcp_receive(TCP_Connection conn, char* buffer, int buffer_size) { return recv(conn.sockfd, buffer, buffer_size, 0); } void tcp_close(TCP_Connection conn) { close(conn.sockfd); } ``` 封装特点:提供面向连接的API接口,隐藏底层socket细节[^4] #### 三、代码对比说明 | 特性 | C#实现 | C语言封装 | |------------|---------------------------|-----------------------| | 开发效率 | 高级API,快速开发 | 需要手动封装底层操作 | | 跨平台性 | 依赖.NET运行时 | 依赖标准C库,移植性强 | | 内存管理 | 自动垃圾回收 | 需手动管理资源 | | 典型应用场景 | 企业级应用开发 | 嵌入式系统/底层网络编程 | #### 四、代码编译使用 C语言封装库编译: ```bash gcc -fPIC -shared network.c -o libnetwork.so sudo cp libnetwork.so /usr/lib/ sudo cp network.h /usr/include/ ``` 使用示例: ```c #include "network.h" TCP_Connection conn = tcp_connect("127.0.0.1", 8888); tcp_send(conn, "Hello from C", 12); char buffer[1024]; int recv_len = tcp_receive(conn, buffer, sizeof(buffer)); tcp_close(conn); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值